Import the part of Nouveau that got eaten by CVS default ignore patterns.

No, this is *not* a core file.  This is a directory with most of the
source code!
This commit is contained in:
riastradh 2014-07-17 01:50:57 +00:00
parent f0744b1ae9
commit cd1be69630
467 changed files with 99476 additions and 0 deletions

View File

@ -0,0 +1,112 @@
/*
* 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/object.h>
#include <core/client.h>
#include <core/handle.h>
#include <core/option.h>
#include <engine/device.h>
static void
nouveau_client_dtor(struct nouveau_object *object)
{
struct nouveau_client *client = (void *)object;
nouveau_object_ref(NULL, &client->device);
nouveau_handle_destroy(client->root);
nouveau_namedb_destroy(&client->base);
}
static struct nouveau_oclass
nouveau_client_oclass = {
.ofuncs = &(struct nouveau_ofuncs) {
.dtor = nouveau_client_dtor,
},
};
int
nouveau_client_create_(const char *name, u64 devname, const char *cfg,
const char *dbg, int length, void **pobject)
{
struct nouveau_object *device;
struct nouveau_client *client;
int ret;
device = (void *)nouveau_device_find(devname);
if (!device)
return -ENODEV;
ret = nouveau_namedb_create_(NULL, NULL, &nouveau_client_oclass,
NV_CLIENT_CLASS, NULL,
(1ULL << NVDEV_ENGINE_DEVICE),
length, pobject);
client = *pobject;
if (ret)
return ret;
ret = nouveau_handle_create(nv_object(client), ~0, ~0,
nv_object(client), &client->root);
if (ret)
return ret;
/* prevent init/fini being called, os in in charge of this */
atomic_set(&nv_object(client)->usecount, 2);
nouveau_object_ref(device, &client->device);
snprintf(client->name, sizeof(client->name), "%s", name);
client->debug = nouveau_dbgopt(dbg, "CLIENT");
return 0;
}
int
nouveau_client_init(struct nouveau_client *client)
{
int ret;
nv_debug(client, "init running\n");
ret = nouveau_handle_init(client->root);
nv_debug(client, "init completed with %d\n", ret);
return ret;
}
int
nouveau_client_fini(struct nouveau_client *client, bool suspend)
{
const char *name[2] = { "fini", "suspend" };
int ret;
nv_debug(client, "%s running\n", name[suspend]);
ret = nouveau_handle_fini(client->root, suspend);
nv_debug(client, "%s completed with %d\n", name[suspend], ret);
return ret;
}
const char *
nouveau_client_name(void *obj)
{
const char *client_name = "unknown";
struct nouveau_client *client = nouveau_client(obj);
if (client)
client_name = client->name;
return client_name;
}

View File

@ -0,0 +1,251 @@
/*
* 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/object.h>
#include <core/namedb.h>
#include <core/handle.h>
#include <core/client.h>
#include <core/engctx.h>
#include <subdev/vm.h>
static inline int
nouveau_engctx_exists(struct nouveau_object *parent,
struct nouveau_engine *engine, void **pobject)
{
struct nouveau_engctx *engctx;
struct nouveau_object *parctx;
list_for_each_entry(engctx, &engine->contexts, head) {
parctx = nv_pclass(nv_object(engctx), NV_PARENT_CLASS);
if (parctx == parent) {
atomic_inc(&nv_object(engctx)->refcount);
*pobject = engctx;
return 1;
}
}
return 0;
}
int
nouveau_engctx_create_(struct nouveau_object *parent,
struct nouveau_object *engobj,
struct nouveau_oclass *oclass,
struct nouveau_object *pargpu,
u32 size, u32 align, u32 flags,
int length, void **pobject)
{
struct nouveau_client *client = nouveau_client(parent);
struct nouveau_engine *engine = nv_engine(engobj);
struct nouveau_object *engctx;
unsigned long save;
int ret;
/* check if this engine already has a context for the parent object,
* and reference it instead of creating a new one
*/
spin_lock_irqsave(&engine->lock, save);
ret = nouveau_engctx_exists(parent, engine, pobject);
spin_unlock_irqrestore(&engine->lock, save);
if (ret)
return ret;
/* create the new context, supports creating both raw objects and
* objects backed by instance memory
*/
if (size) {
ret = nouveau_gpuobj_create_(parent, engobj, oclass,
NV_ENGCTX_CLASS,
pargpu, size, align, flags,
length, pobject);
} else {
ret = nouveau_object_create_(parent, engobj, oclass,
NV_ENGCTX_CLASS, length, pobject);
}
engctx = *pobject;
if (ret)
return ret;
/* must take the lock again and re-check a context doesn't already
* exist (in case of a race) - the lock had to be dropped before as
* it's not possible to allocate the object with it held.
*/
spin_lock_irqsave(&engine->lock, save);
ret = nouveau_engctx_exists(parent, engine, pobject);
if (ret) {
spin_unlock_irqrestore(&engine->lock, save);
nouveau_object_ref(NULL, &engctx);
return ret;
}
if (client->vm)
atomic_inc(&client->vm->engref[nv_engidx(engobj)]);
list_add(&nv_engctx(engctx)->head, &engine->contexts);
nv_engctx(engctx)->addr = ~0ULL;
spin_unlock_irqrestore(&engine->lock, save);
return 0;
}
void
nouveau_engctx_destroy(struct nouveau_engctx *engctx)
{
struct nouveau_object *engobj = nv_object(engctx)->engine;
struct nouveau_engine *engine = nv_engine(engobj);
struct nouveau_client *client = nouveau_client(engctx);
unsigned long save;
nouveau_gpuobj_unmap(&engctx->vma);
spin_lock_irqsave(&engine->lock, save);
list_del(&engctx->head);
spin_unlock_irqrestore(&engine->lock, save);
if (client->vm)
atomic_dec(&client->vm->engref[nv_engidx(engobj)]);
if (engctx->base.size)
nouveau_gpuobj_destroy(&engctx->base);
else
nouveau_object_destroy(&engctx->base.base);
}
int
nouveau_engctx_init(struct nouveau_engctx *engctx)
{
struct nouveau_object *object = nv_object(engctx);
struct nouveau_subdev *subdev = nv_subdev(object->engine);
struct nouveau_object *parent;
struct nouveau_subdev *pardev;
int ret;
ret = nouveau_gpuobj_init(&engctx->base);
if (ret)
return ret;
parent = nv_pclass(object->parent, NV_PARENT_CLASS);
pardev = nv_subdev(parent->engine);
if (nv_parent(parent)->context_attach) {
mutex_lock(&pardev->mutex);
ret = nv_parent(parent)->context_attach(parent, object);
mutex_unlock(&pardev->mutex);
}
if (ret) {
nv_error(parent, "failed to attach %s context, %d\n",
subdev->name, ret);
return ret;
}
nv_debug(parent, "attached %s context\n", subdev->name);
return 0;
}
int
nouveau_engctx_fini(struct nouveau_engctx *engctx, bool suspend)
{
struct nouveau_object *object = nv_object(engctx);
struct nouveau_subdev *subdev = nv_subdev(object->engine);
struct nouveau_object *parent;
struct nouveau_subdev *pardev;
int ret = 0;
parent = nv_pclass(object->parent, NV_PARENT_CLASS);
pardev = nv_subdev(parent->engine);
if (nv_parent(parent)->context_detach) {
mutex_lock(&pardev->mutex);
ret = nv_parent(parent)->context_detach(parent, suspend, object);
mutex_unlock(&pardev->mutex);
}
if (ret) {
nv_error(parent, "failed to detach %s context, %d\n",
subdev->name, ret);
return ret;
}
nv_debug(parent, "detached %s context\n", subdev->name);
return nouveau_gpuobj_fini(&engctx->base, suspend);
}
int
_nouveau_engctx_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_engctx *engctx;
int ret;
ret = nouveau_engctx_create(parent, engine, oclass, NULL, 256, 256,
NVOBJ_FLAG_ZERO_ALLOC, &engctx);
*pobject = nv_object(engctx);
return ret;
}
void
_nouveau_engctx_dtor(struct nouveau_object *object)
{
nouveau_engctx_destroy(nv_engctx(object));
}
int
_nouveau_engctx_init(struct nouveau_object *object)
{
return nouveau_engctx_init(nv_engctx(object));
}
int
_nouveau_engctx_fini(struct nouveau_object *object, bool suspend)
{
return nouveau_engctx_fini(nv_engctx(object), suspend);
}
struct nouveau_object *
nouveau_engctx_get(struct nouveau_engine *engine, u64 addr)
{
struct nouveau_engctx *engctx;
unsigned long flags;
spin_lock_irqsave(&engine->lock, flags);
list_for_each_entry(engctx, &engine->contexts, head) {
if (engctx->addr == addr) {
engctx->save = flags;
return nv_object(engctx);
}
}
spin_unlock_irqrestore(&engine->lock, flags);
return NULL;
}
void
nouveau_engctx_put(struct nouveau_object *object)
{
if (object) {
struct nouveau_engine *engine = nv_engine(object->engine);
struct nouveau_engctx *engctx = nv_engctx(object);
spin_unlock_irqrestore(&engine->lock, engctx->save);
}
}

View File

@ -0,0 +1,68 @@
/*
* 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/device.h>
#include <core/engine.h>
#include <core/option.h>
int
nouveau_engine_create_(struct nouveau_object *parent,
struct nouveau_object *engobj,
struct nouveau_oclass *oclass, bool enable,
const char *iname, const char *fname,
int length, void **pobject)
{
struct nouveau_engine *engine;
int ret;
ret = nouveau_subdev_create_(parent, engobj, oclass, NV_ENGINE_CLASS,
iname, fname, length, pobject);
engine = *pobject;
if (ret)
return ret;
if (parent) {
struct nouveau_device *device = nv_device(parent);
int engidx = nv_engidx(nv_object(engine));
if (device->disable_mask & (1ULL << engidx)) {
if (!nouveau_boolopt(device->cfgopt, iname, false)) {
nv_debug(engine, "engine disabled by hw/fw\n");
return -ENODEV;
}
nv_warn(engine, "ignoring hw/fw engine disable\n");
}
if (!nouveau_boolopt(device->cfgopt, iname, enable)) {
if (!enable)
nv_warn(engine, "disabled, %s=1 to enable\n", iname);
return -ENODEV;
}
}
INIT_LIST_HEAD(&engine->contexts);
spin_lock_init(&engine->lock);
return 0;
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2010 Nouveau Project
*
* All Rights Reserved.
*
* 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 (including the
* next paragraph) 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 OWNER(S) AND/OR ITS SUPPLIERS 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.
*
*/
#include <core/os.h>
#include <core/enum.h>
const struct nouveau_enum *
nouveau_enum_find(const struct nouveau_enum *en, u32 value)
{
while (en->name) {
if (en->value == value)
return en;
en++;
}
return NULL;
}
const struct nouveau_enum *
nouveau_enum_print(const struct nouveau_enum *en, u32 value)
{
en = nouveau_enum_find(en, value);
if (en)
pr_cont("%s", en->name);
else
pr_cont("(unknown enum 0x%08x)", value);
return en;
}
void
nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value)
{
while (bf->name) {
if (value & bf->mask) {
pr_cont(" %s", bf->name);
value &= ~bf->mask;
}
bf++;
}
if (value)
pr_cont(" (unknown bits 0x%08x)", value);
}

View File

@ -0,0 +1,163 @@
/*
* 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.
*/
#include <core/os.h>
#include <core/event.h>
void
nouveau_event_put(struct nouveau_eventh *handler)
{
struct nouveau_event *event = handler->event;
unsigned long flags;
if (__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) {
spin_lock_irqsave(&event->refs_lock, flags);
if (!--event->index[handler->index].refs) {
if (event->disable)
event->disable(event, handler->index);
}
spin_unlock_irqrestore(&event->refs_lock, flags);
}
}
void
nouveau_event_get(struct nouveau_eventh *handler)
{
struct nouveau_event *event = handler->event;
unsigned long flags;
if (!__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) {
spin_lock_irqsave(&event->refs_lock, flags);
if (!event->index[handler->index].refs++) {
if (event->enable)
event->enable(event, handler->index);
}
spin_unlock_irqrestore(&event->refs_lock, flags);
}
}
static void
nouveau_event_fini(struct nouveau_eventh *handler)
{
struct nouveau_event *event = handler->event;
unsigned long flags;
nouveau_event_put(handler);
spin_lock_irqsave(&event->list_lock, flags);
list_del(&handler->head);
spin_unlock_irqrestore(&event->list_lock, flags);
}
static int
nouveau_event_init(struct nouveau_event *event, int index,
int (*func)(void *, int), void *priv,
struct nouveau_eventh *handler)
{
unsigned long flags;
if (index >= event->index_nr)
return -EINVAL;
handler->event = event;
handler->flags = 0;
handler->index = index;
handler->func = func;
handler->priv = priv;
spin_lock_irqsave(&event->list_lock, flags);
list_add_tail(&handler->head, &event->index[index].list);
spin_unlock_irqrestore(&event->list_lock, flags);
return 0;
}
int
nouveau_event_new(struct nouveau_event *event, int index,
int (*func)(void *, int), void *priv,
struct nouveau_eventh **phandler)
{
struct nouveau_eventh *handler;
int ret = -ENOMEM;
handler = *phandler = kmalloc(sizeof(*handler), GFP_KERNEL);
if (handler) {
ret = nouveau_event_init(event, index, func, priv, handler);
if (ret)
kfree(handler);
}
return ret;
}
void
nouveau_event_ref(struct nouveau_eventh *handler, struct nouveau_eventh **ref)
{
BUG_ON(handler != NULL);
if (*ref) {
nouveau_event_fini(*ref);
kfree(*ref);
}
*ref = handler;
}
void
nouveau_event_trigger(struct nouveau_event *event, int index)
{
struct nouveau_eventh *handler;
unsigned long flags;
if (WARN_ON(index >= event->index_nr))
return;
spin_lock_irqsave(&event->list_lock, flags);
list_for_each_entry(handler, &event->index[index].list, head) {
if (test_bit(NVKM_EVENT_ENABLE, &handler->flags) &&
handler->func(handler->priv, index) == NVKM_EVENT_DROP)
nouveau_event_put(handler);
}
spin_unlock_irqrestore(&event->list_lock, flags);
}
void
nouveau_event_destroy(struct nouveau_event **pevent)
{
struct nouveau_event *event = *pevent;
if (event) {
kfree(event);
*pevent = NULL;
}
}
int
nouveau_event_create(int index_nr, struct nouveau_event **pevent)
{
struct nouveau_event *event;
int i;
event = *pevent = kzalloc(sizeof(*event) + index_nr *
sizeof(event->index[0]), GFP_KERNEL);
if (!event)
return -ENOMEM;
spin_lock_init(&event->list_lock);
spin_lock_init(&event->refs_lock);
for (i = 0; i < index_nr; i++)
INIT_LIST_HEAD(&event->index[i].list);
event->index_nr = index_nr;
return 0;
}

View File

@ -0,0 +1,323 @@
/*
* 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/object.h>
#include <core/gpuobj.h>
#include <subdev/instmem.h>
#include <subdev/bar.h>
#include <subdev/vm.h>
void
nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
{
int i;
if (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE) {
for (i = 0; i < gpuobj->size; i += 4)
nv_wo32(gpuobj, i, 0x00000000);
}
if (gpuobj->node) {
nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
&gpuobj->node);
}
if (gpuobj->heap.block_size)
nouveau_mm_fini(&gpuobj->heap);
nouveau_object_destroy(&gpuobj->base);
}
int
nouveau_gpuobj_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, u32 pclass,
struct nouveau_object *pargpu,
u32 size, u32 align, u32 flags,
int length, void **pobject)
{
struct nouveau_instmem *imem = nouveau_instmem(parent);
struct nouveau_bar *bar = nouveau_bar(parent);
struct nouveau_gpuobj *gpuobj;
struct nouveau_mm *heap = NULL;
int ret, i;
u64 addr;
*pobject = NULL;
if (pargpu) {
while ((pargpu = nv_pclass(pargpu, NV_GPUOBJ_CLASS))) {
if (nv_gpuobj(pargpu)->heap.block_size)
break;
pargpu = pargpu->parent;
}
if (unlikely(pargpu == NULL)) {
nv_error(parent, "no gpuobj heap\n");
return -EINVAL;
}
addr = nv_gpuobj(pargpu)->addr;
heap = &nv_gpuobj(pargpu)->heap;
atomic_inc(&parent->refcount);
} else {
ret = imem->alloc(imem, parent, size, align, &parent);
pargpu = parent;
if (ret)
return ret;
addr = nv_memobj(pargpu)->addr;
size = nv_memobj(pargpu)->size;
if (bar && bar->alloc) {
struct nouveau_instobj *iobj = (void *)parent;
struct nouveau_mem **mem = (void *)(iobj + 1);
struct nouveau_mem *node = *mem;
if (!bar->alloc(bar, parent, node, &pargpu)) {
nouveau_object_ref(NULL, &parent);
parent = pargpu;
}
}
}
ret = nouveau_object_create_(parent, engine, oclass, pclass |
NV_GPUOBJ_CLASS, length, pobject);
nouveau_object_ref(NULL, &parent);
gpuobj = *pobject;
if (ret)
return ret;
gpuobj->parent = pargpu;
gpuobj->flags = flags;
gpuobj->addr = addr;
gpuobj->size = size;
if (heap) {
ret = nouveau_mm_head(heap, 1, size, size,
max(align, (u32)1), &gpuobj->node);
if (ret)
return ret;
gpuobj->addr += gpuobj->node->offset;
}
if (gpuobj->flags & NVOBJ_FLAG_HEAP) {
ret = nouveau_mm_init(&gpuobj->heap, 0, gpuobj->size, 1);
if (ret)
return ret;
}
if (flags & NVOBJ_FLAG_ZERO_ALLOC) {
for (i = 0; i < gpuobj->size; i += 4)
nv_wo32(gpuobj, i, 0x00000000);
}
return ret;
}
struct nouveau_gpuobj_class {
struct nouveau_object *pargpu;
u64 size;
u32 align;
u32 flags;
};
static int
_nouveau_gpuobj_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_gpuobj_class *args = data;
struct nouveau_gpuobj *object;
int ret;
ret = nouveau_gpuobj_create(parent, engine, oclass, 0, args->pargpu,
args->size, args->align, args->flags,
&object);
*pobject = nv_object(object);
if (ret)
return ret;
return 0;
}
void
_nouveau_gpuobj_dtor(struct nouveau_object *object)
{
nouveau_gpuobj_destroy(nv_gpuobj(object));
}
int
_nouveau_gpuobj_init(struct nouveau_object *object)
{
return nouveau_gpuobj_init(nv_gpuobj(object));
}
int
_nouveau_gpuobj_fini(struct nouveau_object *object, bool suspend)
{
return nouveau_gpuobj_fini(nv_gpuobj(object), suspend);
}
u32
_nouveau_gpuobj_rd32(struct nouveau_object *object, u64 addr)
{
struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
if (gpuobj->node)
addr += gpuobj->node->offset;
return pfuncs->rd32(gpuobj->parent, addr);
}
void
_nouveau_gpuobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
{
struct nouveau_gpuobj *gpuobj = nv_gpuobj(object);
struct nouveau_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
if (gpuobj->node)
addr += gpuobj->node->offset;
pfuncs->wr32(gpuobj->parent, addr, data);
}
static struct nouveau_oclass
_nouveau_gpuobj_oclass = {
.handle = 0x00000000,
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_gpuobj_ctor,
.dtor = _nouveau_gpuobj_dtor,
.init = _nouveau_gpuobj_init,
.fini = _nouveau_gpuobj_fini,
.rd32 = _nouveau_gpuobj_rd32,
.wr32 = _nouveau_gpuobj_wr32,
},
};
int
nouveau_gpuobj_new(struct nouveau_object *parent, struct nouveau_object *pargpu,
u32 size, u32 align, u32 flags,
struct nouveau_gpuobj **pgpuobj)
{
struct nouveau_object *engine = parent;
struct nouveau_gpuobj_class args = {
.pargpu = pargpu,
.size = size,
.align = align,
.flags = flags,
};
if (!nv_iclass(engine, NV_SUBDEV_CLASS))
engine = engine->engine;
BUG_ON(engine == NULL);
return nouveau_object_ctor(parent, engine, &_nouveau_gpuobj_oclass,
&args, sizeof(args),
(struct nouveau_object **)pgpuobj);
}
int
nouveau_gpuobj_map(struct nouveau_gpuobj *gpuobj, u32 access,
struct nouveau_vma *vma)
{
struct nouveau_bar *bar = nouveau_bar(gpuobj);
int ret = -EINVAL;
if (bar && bar->umap) {
struct nouveau_instobj *iobj = (void *)
nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
struct nouveau_mem **mem = (void *)(iobj + 1);
ret = bar->umap(bar, *mem, access, vma);
}
return ret;
}
int
nouveau_gpuobj_map_vm(struct nouveau_gpuobj *gpuobj, struct nouveau_vm *vm,
u32 access, struct nouveau_vma *vma)
{
struct nouveau_instobj *iobj = (void *)
nv_pclass(nv_object(gpuobj), NV_MEMOBJ_CLASS);
struct nouveau_mem **mem = (void *)(iobj + 1);
int ret;
ret = nouveau_vm_get(vm, gpuobj->size, 12, access, vma);
if (ret)
return ret;
nouveau_vm_map(vma, *mem);
return 0;
}
void
nouveau_gpuobj_unmap(struct nouveau_vma *vma)
{
if (vma->node) {
nouveau_vm_unmap(vma);
nouveau_vm_put(vma);
}
}
/* the below is basically only here to support sharing the paged dma object
* for PCI(E)GART on <=nv4x chipsets, and should *not* be expected to work
* anywhere else.
*/
static void
nouveau_gpudup_dtor(struct nouveau_object *object)
{
struct nouveau_gpuobj *gpuobj = (void *)object;
nouveau_object_ref(NULL, &gpuobj->parent);
nouveau_object_destroy(&gpuobj->base);
}
static struct nouveau_oclass
nouveau_gpudup_oclass = {
.handle = NV_GPUOBJ_CLASS,
.ofuncs = &(struct nouveau_ofuncs) {
.dtor = nouveau_gpudup_dtor,
.init = nouveau_object_init,
.fini = nouveau_object_fini,
},
};
int
nouveau_gpuobj_dup(struct nouveau_object *parent, struct nouveau_gpuobj *base,
struct nouveau_gpuobj **pgpuobj)
{
struct nouveau_gpuobj *gpuobj;
int ret;
ret = nouveau_object_create(parent, parent->engine,
&nouveau_gpudup_oclass, 0, &gpuobj);
*pgpuobj = gpuobj;
if (ret)
return ret;
nouveau_object_ref(nv_object(base), &gpuobj->parent);
gpuobj->addr = base->addr;
gpuobj->size = base->size;
return 0;
}

View File

@ -0,0 +1,226 @@
/*
* 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/object.h>
#include <core/handle.h>
#include <core/client.h>
#define hprintk(h,l,f,a...) do { \
struct nouveau_client *c = nouveau_client((h)->object); \
struct nouveau_handle *p = (h)->parent; u32 n = p ? p->name : ~0; \
nv_printk((c), l, "0x%08x:0x%08x "f, n, (h)->name, ##a); \
} while(0)
int
nouveau_handle_init(struct nouveau_handle *handle)
{
struct nouveau_handle *item;
int ret;
hprintk(handle, TRACE, "init running\n");
ret = nouveau_object_inc(handle->object);
if (ret)
return ret;
hprintk(handle, TRACE, "init children\n");
list_for_each_entry(item, &handle->tree, head) {
ret = nouveau_handle_init(item);
if (ret)
goto fail;
}
hprintk(handle, TRACE, "init completed\n");
return 0;
fail:
hprintk(handle, ERROR, "init failed with %d\n", ret);
list_for_each_entry_continue_reverse(item, &handle->tree, head) {
nouveau_handle_fini(item, false);
}
nouveau_object_dec(handle->object, false);
return ret;
}
int
nouveau_handle_fini(struct nouveau_handle *handle, bool suspend)
{
static char *name[2] = { "fini", "suspend" };
struct nouveau_handle *item;
int ret;
hprintk(handle, TRACE, "%s children\n", name[suspend]);
list_for_each_entry(item, &handle->tree, head) {
ret = nouveau_handle_fini(item, suspend);
if (ret && suspend)
goto fail;
}
hprintk(handle, TRACE, "%s running\n", name[suspend]);
if (handle->object) {
ret = nouveau_object_dec(handle->object, suspend);
if (ret && suspend)
goto fail;
}
hprintk(handle, TRACE, "%s completed\n", name[suspend]);
return 0;
fail:
hprintk(handle, ERROR, "%s failed with %d\n", name[suspend], ret);
list_for_each_entry_continue_reverse(item, &handle->tree, head) {
int rret = nouveau_handle_init(item);
if (rret)
hprintk(handle, FATAL, "failed to restart, %d\n", rret);
}
return ret;
}
int
nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
struct nouveau_object *object,
struct nouveau_handle **phandle)
{
struct nouveau_object *namedb;
struct nouveau_handle *handle;
int ret;
namedb = parent;
while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
namedb = namedb->parent;
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
if (!handle)
return -ENOMEM;
INIT_LIST_HEAD(&handle->head);
INIT_LIST_HEAD(&handle->tree);
handle->name = _handle;
handle->priv = ~0;
ret = nouveau_namedb_insert(nv_namedb(namedb), _handle, object, handle);
if (ret) {
kfree(handle);
return ret;
}
if (nv_parent(parent)->object_attach) {
ret = nv_parent(parent)->object_attach(parent, object, _handle);
if (ret < 0) {
nouveau_handle_destroy(handle);
return ret;
}
handle->priv = ret;
}
if (object != namedb) {
while (!nv_iclass(namedb, NV_CLIENT_CLASS))
namedb = namedb->parent;
handle->parent = nouveau_namedb_get(nv_namedb(namedb), _parent);
if (handle->parent) {
list_add(&handle->head, &handle->parent->tree);
nouveau_namedb_put(handle->parent);
}
}
hprintk(handle, TRACE, "created\n");
*phandle = handle;
return 0;
}
void
nouveau_handle_destroy(struct nouveau_handle *handle)
{
struct nouveau_handle *item, *temp;
hprintk(handle, TRACE, "destroy running\n");
list_for_each_entry_safe(item, temp, &handle->tree, head) {
nouveau_handle_destroy(item);
}
list_del(&handle->head);
if (handle->priv != ~0) {
struct nouveau_object *parent = handle->parent->object;
nv_parent(parent)->object_detach(parent, handle->priv);
}
hprintk(handle, TRACE, "destroy completed\n");
nouveau_namedb_remove(handle);
kfree(handle);
}
struct nouveau_object *
nouveau_handle_ref(struct nouveau_object *parent, u32 name)
{
struct nouveau_object *object = NULL;
struct nouveau_handle *handle;
while (!nv_iclass(parent, NV_NAMEDB_CLASS))
parent = parent->parent;
handle = nouveau_namedb_get(nv_namedb(parent), name);
if (handle) {
nouveau_object_ref(handle->object, &object);
nouveau_namedb_put(handle);
}
return object;
}
struct nouveau_handle *
nouveau_handle_get_class(struct nouveau_object *engctx, u16 oclass)
{
struct nouveau_namedb *namedb;
if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
return nouveau_namedb_get_class(namedb, oclass);
return NULL;
}
struct nouveau_handle *
nouveau_handle_get_vinst(struct nouveau_object *engctx, u64 vinst)
{
struct nouveau_namedb *namedb;
if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
return nouveau_namedb_get_vinst(namedb, vinst);
return NULL;
}
struct nouveau_handle *
nouveau_handle_get_cinst(struct nouveau_object *engctx, u32 cinst)
{
struct nouveau_namedb *namedb;
if (engctx && (namedb = (void *)nv_pclass(engctx, NV_NAMEDB_CLASS)))
return nouveau_namedb_get_cinst(namedb, cinst);
return NULL;
}
void
nouveau_handle_put(struct nouveau_handle *handle)
{
if (handle)
nouveau_namedb_put(handle);
}

View File

@ -0,0 +1,254 @@
/*
* 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/os.h"
#include "core/mm.h"
#define node(root, dir) ((root)->nl_entry.dir == &mm->nodes) ? NULL : \
list_entry((root)->nl_entry.dir, struct nouveau_mm_node, nl_entry)
void
nouveau_mm_free(struct nouveau_mm *mm, struct nouveau_mm_node **pthis)
{
struct nouveau_mm_node *this = *pthis;
if (this) {
struct nouveau_mm_node *prev = node(this, prev);
struct nouveau_mm_node *next = node(this, next);
if (prev && prev->type == 0) {
prev->length += this->length;
list_del(&this->nl_entry);
kfree(this); this = prev;
}
if (next && next->type == 0) {
next->offset = this->offset;
next->length += this->length;
if (this->type == 0)
list_del(&this->fl_entry);
list_del(&this->nl_entry);
kfree(this); this = NULL;
}
if (this && this->type != 0) {
list_for_each_entry(prev, &mm->free, fl_entry) {
if (this->offset < prev->offset)
break;
}
list_add_tail(&this->fl_entry, &prev->fl_entry);
this->type = 0;
}
}
*pthis = NULL;
}
static struct nouveau_mm_node *
region_head(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
{
struct nouveau_mm_node *b;
if (a->length == size)
return a;
b = kmalloc(sizeof(*b), GFP_KERNEL);
if (unlikely(b == NULL))
return NULL;
b->offset = a->offset;
b->length = size;
b->type = a->type;
a->offset += size;
a->length -= size;
list_add_tail(&b->nl_entry, &a->nl_entry);
if (b->type == 0)
list_add_tail(&b->fl_entry, &a->fl_entry);
return b;
}
int
nouveau_mm_head(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
u32 align, struct nouveau_mm_node **pnode)
{
struct nouveau_mm_node *prev, *this, *next;
u32 mask = align - 1;
u32 splitoff;
u32 s, e;
BUG_ON(!type);
list_for_each_entry(this, &mm->free, fl_entry) {
e = this->offset + this->length;
s = this->offset;
prev = node(this, prev);
if (prev && prev->type != type)
s = roundup(s, mm->block_size);
next = node(this, next);
if (next && next->type != type)
e = rounddown(e, mm->block_size);
s = (s + mask) & ~mask;
e &= ~mask;
if (s > e || e - s < size_min)
continue;
splitoff = s - this->offset;
if (splitoff && !region_head(mm, this, splitoff))
return -ENOMEM;
this = region_head(mm, this, min(size_max, e - s));
if (!this)
return -ENOMEM;
this->type = type;
list_del(&this->fl_entry);
*pnode = this;
return 0;
}
return -ENOSPC;
}
static struct nouveau_mm_node *
region_tail(struct nouveau_mm *mm, struct nouveau_mm_node *a, u32 size)
{
struct nouveau_mm_node *b;
if (a->length == size)
return a;
b = kmalloc(sizeof(*b), GFP_KERNEL);
if (unlikely(b == NULL))
return NULL;
a->length -= size;
b->offset = a->offset + a->length;
b->length = size;
b->type = a->type;
list_add(&b->nl_entry, &a->nl_entry);
if (b->type == 0)
list_add(&b->fl_entry, &a->fl_entry);
return b;
}
int
nouveau_mm_tail(struct nouveau_mm *mm, u8 type, u32 size_max, u32 size_min,
u32 align, struct nouveau_mm_node **pnode)
{
struct nouveau_mm_node *prev, *this, *next;
u32 mask = align - 1;
BUG_ON(!type);
list_for_each_entry_reverse(this, &mm->free, fl_entry) {
u32 e = this->offset + this->length;
u32 s = this->offset;
u32 c = 0, a;
prev = node(this, prev);
if (prev && prev->type != type)
s = roundup(s, mm->block_size);
next = node(this, next);
if (next && next->type != type) {
e = rounddown(e, mm->block_size);
c = next->offset - e;
}
s = (s + mask) & ~mask;
a = e - s;
if (s > e || a < size_min)
continue;
a = min(a, size_max);
s = (e - a) & ~mask;
c += (e - s) - a;
if (c && !region_tail(mm, this, c))
return -ENOMEM;
this = region_tail(mm, this, a);
if (!this)
return -ENOMEM;
this->type = type;
list_del(&this->fl_entry);
*pnode = this;
return 0;
}
return -ENOSPC;
}
int
nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
{
struct nouveau_mm_node *node;
if (block) {
INIT_LIST_HEAD(&mm->nodes);
INIT_LIST_HEAD(&mm->free);
mm->block_size = block;
mm->heap_nodes = 0;
}
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return -ENOMEM;
if (length) {
node->offset = roundup(offset, mm->block_size);
node->length = rounddown(offset + length, mm->block_size);
node->length -= node->offset;
}
list_add_tail(&node->nl_entry, &mm->nodes);
list_add_tail(&node->fl_entry, &mm->free);
mm->heap_nodes++;
return 0;
}
int
nouveau_mm_fini(struct nouveau_mm *mm)
{
if (nouveau_mm_initialised(mm)) {
struct nouveau_mm_node *node, *heap =
list_first_entry(&mm->nodes, typeof(*heap), nl_entry);
int nodes = 0;
list_for_each_entry(node, &mm->nodes, nl_entry) {
if (WARN_ON(nodes++ == mm->heap_nodes))
return -EBUSY;
}
kfree(heap);
}
return 0;
}

View File

@ -0,0 +1,203 @@
/*
* 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/object.h>
#include <core/namedb.h>
#include <core/handle.h>
#include <core/gpuobj.h>
static struct nouveau_handle *
nouveau_namedb_lookup(struct nouveau_namedb *namedb, u32 name)
{
struct nouveau_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (handle->name == name)
return handle;
}
return NULL;
}
static struct nouveau_handle *
nouveau_namedb_lookup_class(struct nouveau_namedb *namedb, u16 oclass)
{
struct nouveau_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (nv_mclass(handle->object) == oclass)
return handle;
}
return NULL;
}
static struct nouveau_handle *
nouveau_namedb_lookup_vinst(struct nouveau_namedb *namedb, u64 vinst)
{
struct nouveau_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
if (nv_gpuobj(handle->object)->addr == vinst)
return handle;
}
}
return NULL;
}
static struct nouveau_handle *
nouveau_namedb_lookup_cinst(struct nouveau_namedb *namedb, u32 cinst)
{
struct nouveau_handle *handle;
list_for_each_entry(handle, &namedb->list, node) {
if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) {
if (nv_gpuobj(handle->object)->node &&
nv_gpuobj(handle->object)->node->offset == cinst)
return handle;
}
}
return NULL;
}
int
nouveau_namedb_insert(struct nouveau_namedb *namedb, u32 name,
struct nouveau_object *object,
struct nouveau_handle *handle)
{
int ret = -EEXIST;
write_lock_irq(&namedb->lock);
if (!nouveau_namedb_lookup(namedb, name)) {
nouveau_object_ref(object, &handle->object);
handle->namedb = namedb;
list_add(&handle->node, &namedb->list);
ret = 0;
}
write_unlock_irq(&namedb->lock);
return ret;
}
void
nouveau_namedb_remove(struct nouveau_handle *handle)
{
struct nouveau_namedb *namedb = handle->namedb;
struct nouveau_object *object = handle->object;
write_lock_irq(&namedb->lock);
list_del(&handle->node);
write_unlock_irq(&namedb->lock);
nouveau_object_ref(NULL, &object);
}
struct nouveau_handle *
nouveau_namedb_get(struct nouveau_namedb *namedb, u32 name)
{
struct nouveau_handle *handle;
read_lock(&namedb->lock);
handle = nouveau_namedb_lookup(namedb, name);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
struct nouveau_handle *
nouveau_namedb_get_class(struct nouveau_namedb *namedb, u16 oclass)
{
struct nouveau_handle *handle;
read_lock(&namedb->lock);
handle = nouveau_namedb_lookup_class(namedb, oclass);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
struct nouveau_handle *
nouveau_namedb_get_vinst(struct nouveau_namedb *namedb, u64 vinst)
{
struct nouveau_handle *handle;
read_lock(&namedb->lock);
handle = nouveau_namedb_lookup_vinst(namedb, vinst);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
struct nouveau_handle *
nouveau_namedb_get_cinst(struct nouveau_namedb *namedb, u32 cinst)
{
struct nouveau_handle *handle;
read_lock(&namedb->lock);
handle = nouveau_namedb_lookup_cinst(namedb, cinst);
if (handle == NULL)
read_unlock(&namedb->lock);
return handle;
}
void
nouveau_namedb_put(struct nouveau_handle *handle)
{
if (handle)
read_unlock(&handle->namedb->lock);
}
int
nouveau_namedb_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, u32 pclass,
struct nouveau_oclass *sclass, u64 engcls,
int length, void **pobject)
{
struct nouveau_namedb *namedb;
int ret;
ret = nouveau_parent_create_(parent, engine, oclass, pclass |
NV_NAMEDB_CLASS, sclass, engcls,
length, pobject);
namedb = *pobject;
if (ret)
return ret;
rwlock_init(&namedb->lock);
INIT_LIST_HEAD(&namedb->list);
return 0;
}
int
_nouveau_namedb_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_namedb *object;
int ret;
ret = nouveau_namedb_create(parent, engine, oclass, 0, NULL, 0, &object);
*pobject = nv_object(object);
if (ret)
return ret;
return 0;
}

View File

@ -0,0 +1,474 @@
/*
* 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/object.h>
#include <core/parent.h>
#include <core/namedb.h>
#include <core/handle.h>
#include <core/engine.h>
#ifdef NOUVEAU_OBJECT_MAGIC
static struct list_head _objlist = LIST_HEAD_INIT(_objlist);
static DEFINE_SPINLOCK(_objlist_lock);
#endif
int
nouveau_object_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, u32 pclass,
int size, void **pobject)
{
struct nouveau_object *object;
object = *pobject = kzalloc(size, GFP_KERNEL);
if (!object)
return -ENOMEM;
nouveau_object_ref(parent, &object->parent);
nouveau_object_ref(engine, &object->engine);
object->oclass = oclass;
object->oclass->handle |= pclass;
atomic_set(&object->refcount, 1);
atomic_set(&object->usecount, 0);
#ifdef NOUVEAU_OBJECT_MAGIC
object->_magic = NOUVEAU_OBJECT_MAGIC;
spin_lock(&_objlist_lock);
list_add(&object->list, &_objlist);
spin_unlock(&_objlist_lock);
#endif
return 0;
}
static int
_nouveau_object_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_object *object;
int ret;
ret = nouveau_object_create(parent, engine, oclass, 0, &object);
*pobject = nv_object(object);
if (ret)
return ret;
return 0;
}
void
nouveau_object_destroy(struct nouveau_object *object)
{
#ifdef NOUVEAU_OBJECT_MAGIC
spin_lock(&_objlist_lock);
list_del(&object->list);
spin_unlock(&_objlist_lock);
#endif
nouveau_object_ref(NULL, &object->engine);
nouveau_object_ref(NULL, &object->parent);
kfree(object);
}
static void
_nouveau_object_dtor(struct nouveau_object *object)
{
nouveau_object_destroy(object);
}
int
nouveau_object_init(struct nouveau_object *object)
{
return 0;
}
static int
_nouveau_object_init(struct nouveau_object *object)
{
return nouveau_object_init(object);
}
int
nouveau_object_fini(struct nouveau_object *object, bool suspend)
{
return 0;
}
static int
_nouveau_object_fini(struct nouveau_object *object, bool suspend)
{
return nouveau_object_fini(object, suspend);
}
struct nouveau_ofuncs
nouveau_object_ofuncs = {
.ctor = _nouveau_object_ctor,
.dtor = _nouveau_object_dtor,
.init = _nouveau_object_init,
.fini = _nouveau_object_fini,
};
int
nouveau_object_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_ofuncs *ofuncs = oclass->ofuncs;
struct nouveau_object *object = NULL;
int ret;
ret = ofuncs->ctor(parent, engine, oclass, data, size, &object);
*pobject = object;
if (ret < 0) {
if (ret != -ENODEV) {
nv_error(parent, "failed to create 0x%08x, %d\n",
oclass->handle, ret);
}
if (object) {
ofuncs->dtor(object);
*pobject = NULL;
}
return ret;
}
if (ret == 0) {
nv_debug(object, "created\n");
atomic_set(&object->refcount, 1);
}
return 0;
}
static void
nouveau_object_dtor(struct nouveau_object *object)
{
nv_debug(object, "destroying\n");
nv_ofuncs(object)->dtor(object);
}
void
nouveau_object_ref(struct nouveau_object *obj, struct nouveau_object **ref)
{
if (obj) {
atomic_inc(&obj->refcount);
nv_trace(obj, "inc() == %d\n", atomic_read(&obj->refcount));
}
if (*ref) {
int dead = atomic_dec_and_test(&(*ref)->refcount);
nv_trace(*ref, "dec() == %d\n", atomic_read(&(*ref)->refcount));
if (dead)
nouveau_object_dtor(*ref);
}
*ref = obj;
}
int
nouveau_object_new(struct nouveau_object *client, u32 _parent, u32 _handle,
u16 _oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_object *parent = NULL;
struct nouveau_object *engctx = NULL;
struct nouveau_object *object = NULL;
struct nouveau_object *engine;
struct nouveau_oclass *oclass;
struct nouveau_handle *handle;
int ret;
/* lookup parent object and ensure it *is* a parent */
parent = nouveau_handle_ref(client, _parent);
if (!parent) {
nv_error(client, "parent 0x%08x not found\n", _parent);
return -ENOENT;
}
if (!nv_iclass(parent, NV_PARENT_CLASS)) {
nv_error(parent, "cannot have children\n");
ret = -EINVAL;
goto fail_class;
}
/* check that parent supports the requested subclass */
ret = nouveau_parent_sclass(parent, _oclass, &engine, &oclass);
if (ret) {
nv_debug(parent, "illegal class 0x%04x\n", _oclass);
goto fail_class;
}
/* make sure engine init has been completed *before* any objects
* it controls are created - the constructors may depend on
* state calculated at init (ie. default context construction)
*/
if (engine) {
ret = nouveau_object_inc(engine);
if (ret)
goto fail_class;
}
/* if engine requires it, create a context object to insert
* between the parent and its children (eg. PGRAPH context)
*/
if (engine && nv_engine(engine)->cclass) {
ret = nouveau_object_ctor(parent, engine,
nv_engine(engine)->cclass,
data, size, &engctx);
if (ret)
goto fail_engctx;
} else {
nouveau_object_ref(parent, &engctx);
}
/* finally, create new object and bind it to its handle */
ret = nouveau_object_ctor(engctx, engine, oclass, data, size, &object);
*pobject = object;
if (ret)
goto fail_ctor;
ret = nouveau_object_inc(object);
if (ret)
goto fail_init;
ret = nouveau_handle_create(parent, _parent, _handle, object, &handle);
if (ret)
goto fail_handle;
ret = nouveau_handle_init(handle);
if (ret)
nouveau_handle_destroy(handle);
fail_handle:
nouveau_object_dec(object, false);
fail_init:
nouveau_object_ref(NULL, &object);
fail_ctor:
nouveau_object_ref(NULL, &engctx);
fail_engctx:
if (engine)
nouveau_object_dec(engine, false);
fail_class:
nouveau_object_ref(NULL, &parent);
return ret;
}
int
nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle)
{
struct nouveau_object *parent = NULL;
struct nouveau_object *namedb = NULL;
struct nouveau_handle *handle = NULL;
parent = nouveau_handle_ref(client, _parent);
if (!parent)
return -ENOENT;
namedb = nv_pclass(parent, NV_NAMEDB_CLASS);
if (namedb) {
handle = nouveau_namedb_get(nv_namedb(namedb), _handle);
if (handle) {
nouveau_namedb_put(handle);
nouveau_handle_fini(handle, false);
nouveau_handle_destroy(handle);
}
}
nouveau_object_ref(NULL, &parent);
return handle ? 0 : -EINVAL;
}
int
nouveau_object_inc(struct nouveau_object *object)
{
int ref = atomic_add_return(1, &object->usecount);
int ret;
nv_trace(object, "use(+1) == %d\n", atomic_read(&object->usecount));
if (ref != 1)
return 0;
nv_trace(object, "initialising...\n");
if (object->parent) {
ret = nouveau_object_inc(object->parent);
if (ret) {
nv_error(object, "parent failed, %d\n", ret);
goto fail_parent;
}
}
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
ret = nouveau_object_inc(object->engine);
mutex_unlock(&nv_subdev(object->engine)->mutex);
if (ret) {
nv_error(object, "engine failed, %d\n", ret);
goto fail_engine;
}
}
ret = nv_ofuncs(object)->init(object);
atomic_set(&object->usecount, 1);
if (ret) {
nv_error(object, "init failed, %d\n", ret);
goto fail_self;
}
nv_debug(object, "initialised\n");
return 0;
fail_self:
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
nouveau_object_dec(object->engine, false);
mutex_unlock(&nv_subdev(object->engine)->mutex);
}
fail_engine:
if (object->parent)
nouveau_object_dec(object->parent, false);
fail_parent:
atomic_dec(&object->usecount);
return ret;
}
static int
nouveau_object_decf(struct nouveau_object *object)
{
int ret;
nv_trace(object, "stopping...\n");
ret = nv_ofuncs(object)->fini(object, false);
atomic_set(&object->usecount, 0);
if (ret)
nv_warn(object, "failed fini, %d\n", ret);
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
nouveau_object_dec(object->engine, false);
mutex_unlock(&nv_subdev(object->engine)->mutex);
}
if (object->parent)
nouveau_object_dec(object->parent, false);
nv_debug(object, "stopped\n");
return 0;
}
static int
nouveau_object_decs(struct nouveau_object *object)
{
int ret, rret;
nv_trace(object, "suspending...\n");
ret = nv_ofuncs(object)->fini(object, true);
atomic_set(&object->usecount, 0);
if (ret) {
nv_error(object, "failed suspend, %d\n", ret);
return ret;
}
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
ret = nouveau_object_dec(object->engine, true);
mutex_unlock(&nv_subdev(object->engine)->mutex);
if (ret) {
nv_warn(object, "engine failed suspend, %d\n", ret);
goto fail_engine;
}
}
if (object->parent) {
ret = nouveau_object_dec(object->parent, true);
if (ret) {
nv_warn(object, "parent failed suspend, %d\n", ret);
goto fail_parent;
}
}
nv_debug(object, "suspended\n");
return 0;
fail_parent:
if (object->engine) {
mutex_lock(&nv_subdev(object->engine)->mutex);
rret = nouveau_object_inc(object->engine);
mutex_unlock(&nv_subdev(object->engine)->mutex);
if (rret)
nv_fatal(object, "engine failed to reinit, %d\n", rret);
}
fail_engine:
rret = nv_ofuncs(object)->init(object);
if (rret)
nv_fatal(object, "failed to reinit, %d\n", rret);
return ret;
}
int
nouveau_object_dec(struct nouveau_object *object, bool suspend)
{
int ref = atomic_add_return(-1, &object->usecount);
int ret;
nv_trace(object, "use(-1) == %d\n", atomic_read(&object->usecount));
if (ref == 0) {
if (suspend)
ret = nouveau_object_decs(object);
else
ret = nouveau_object_decf(object);
if (ret) {
atomic_inc(&object->usecount);
return ret;
}
}
return 0;
}
void
nouveau_object_debug(void)
{
#ifdef NOUVEAU_OBJECT_MAGIC
struct nouveau_object *object;
if (!list_empty(&_objlist)) {
nv_fatal(NULL, "*******************************************\n");
nv_fatal(NULL, "* AIIIII! object(s) still exist!!!\n");
nv_fatal(NULL, "*******************************************\n");
list_for_each_entry(object, &_objlist, list) {
nv_fatal(object, "%p/%p/%d/%d\n",
object->parent, object->engine,
atomic_read(&object->refcount),
atomic_read(&object->usecount));
}
}
#endif
}

View File

@ -0,0 +1,122 @@
/*
* 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/option.h>
#include <core/debug.h>
const char *
nouveau_stropt(const char *optstr, const char *opt, int *arglen)
{
while (optstr && *optstr != '\0') {
int len = strcspn(optstr, ",=");
switch (optstr[len]) {
case '=':
if (!strncasecmpz(optstr, opt, len)) {
optstr += len + 1;
*arglen = strcspn(optstr, ",=");
return *arglen ? optstr : NULL;
}
optstr++;
break;
case ',':
optstr++;
break;
default:
break;
}
optstr += len;
}
return NULL;
}
bool
nouveau_boolopt(const char *optstr, const char *opt, bool value)
{
int arglen;
optstr = nouveau_stropt(optstr, opt, &arglen);
if (optstr) {
if (!strncasecmpz(optstr, "0", arglen) ||
!strncasecmpz(optstr, "no", arglen) ||
!strncasecmpz(optstr, "off", arglen) ||
!strncasecmpz(optstr, "false", arglen))
value = false;
else
if (!strncasecmpz(optstr, "1", arglen) ||
!strncasecmpz(optstr, "yes", arglen) ||
!strncasecmpz(optstr, "on", arglen) ||
!strncasecmpz(optstr, "true", arglen))
value = true;
}
return value;
}
int
nouveau_dbgopt(const char *optstr, const char *sub)
{
int mode = 1, level = CONFIG_NOUVEAU_DEBUG_DEFAULT;
while (optstr) {
int len = strcspn(optstr, ",=");
switch (optstr[len]) {
case '=':
if (strncasecmpz(optstr, sub, len))
mode = 0;
optstr++;
break;
default:
if (mode) {
if (!strncasecmpz(optstr, "fatal", len))
level = NV_DBG_FATAL;
else if (!strncasecmpz(optstr, "error", len))
level = NV_DBG_ERROR;
else if (!strncasecmpz(optstr, "warn", len))
level = NV_DBG_WARN;
else if (!strncasecmpz(optstr, "info", len))
level = NV_DBG_INFO_NORMAL;
else if (!strncasecmpz(optstr, "debug", len))
level = NV_DBG_DEBUG;
else if (!strncasecmpz(optstr, "trace", len))
level = NV_DBG_TRACE;
else if (!strncasecmpz(optstr, "paranoia", len))
level = NV_DBG_PARANOIA;
else if (!strncasecmpz(optstr, "spam", len))
level = NV_DBG_SPAM;
}
if (optstr[len] != '\0') {
optstr++;
mode = 1;
break;
}
return level;
}
optstr += len;
}
return level;
}

View File

@ -0,0 +1,128 @@
/*
* 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/object.h>
#include <core/parent.h>
#include <core/client.h>
int
nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
struct nouveau_object **pengine,
struct nouveau_oclass **poclass)
{
struct nouveau_sclass *sclass;
struct nouveau_engine *engine;
struct nouveau_oclass *oclass;
u64 mask;
sclass = nv_parent(parent)->sclass;
while (sclass) {
if ((sclass->oclass->handle & 0xffff) == handle) {
*pengine = parent->engine;
*poclass = sclass->oclass;
return 0;
}
sclass = sclass->sclass;
}
mask = nv_parent(parent)->engine;
while (mask) {
int i = __ffs64(mask);
if (nv_iclass(parent, NV_CLIENT_CLASS))
engine = nv_engine(nv_client(parent)->device);
else
engine = nouveau_engine(parent, i);
if (engine) {
oclass = engine->sclass;
while (oclass->ofuncs) {
if ((oclass->handle & 0xffff) == handle) {
*pengine = nv_object(engine);
*poclass = oclass;
return 0;
}
oclass++;
}
}
mask &= ~(1ULL << i);
}
return -EINVAL;
}
int
nouveau_parent_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, u32 pclass,
struct nouveau_oclass *sclass, u64 engcls,
int size, void **pobject)
{
struct nouveau_parent *object;
struct nouveau_sclass *nclass;
int ret;
ret = nouveau_object_create_(parent, engine, oclass, pclass |
NV_PARENT_CLASS, size, pobject);
object = *pobject;
if (ret)
return ret;
while (sclass && sclass->ofuncs) {
nclass = kzalloc(sizeof(*nclass), GFP_KERNEL);
if (!nclass)
return -ENOMEM;
nclass->sclass = object->sclass;
object->sclass = nclass;
nclass->engine = engine ? nv_engine(engine) : NULL;
nclass->oclass = sclass;
sclass++;
}
object->engine = engcls;
return 0;
}
void
nouveau_parent_destroy(struct nouveau_parent *parent)
{
struct nouveau_sclass *sclass;
while ((sclass = parent->sclass)) {
parent->sclass = sclass->sclass;
kfree(sclass);
}
nouveau_object_destroy(&parent->base);
}
void
_nouveau_parent_dtor(struct nouveau_object *object)
{
nouveau_parent_destroy(nv_parent(object));
}

View File

@ -0,0 +1,98 @@
/*
* 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/object.h>
#include <core/client.h>
#include <core/subdev.h>
#include <core/printk.h>
int nv_info_debug_level = NV_DBG_INFO_NORMAL;
void
nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...)
{
static const char name[] = { '!', 'E', 'W', ' ', 'D', 'T', 'P', 'S' };
const char *pfx;
char mfmt[256];
va_list args;
switch (level) {
case NV_DBG_FATAL:
pfx = KERN_CRIT;
break;
case NV_DBG_ERROR:
pfx = KERN_ERR;
break;
case NV_DBG_WARN:
pfx = KERN_WARNING;
break;
case NV_DBG_INFO_NORMAL:
pfx = KERN_INFO;
break;
case NV_DBG_DEBUG:
case NV_DBG_PARANOIA:
case NV_DBG_TRACE:
case NV_DBG_SPAM:
default:
pfx = KERN_DEBUG;
break;
}
if (object && !nv_iclass(object, NV_CLIENT_CLASS)) {
struct nouveau_object *device = object;
struct nouveau_object *subdev = object;
char obuf[64], *ofmt = "";
if (object->engine) {
snprintf(obuf, sizeof(obuf), "[0x%08x][%p]",
nv_hclass(object), object);
ofmt = obuf;
subdev = object->engine;
device = object->engine;
}
if (subdev->parent)
device = subdev->parent;
if (level > nv_subdev(subdev)->debug)
return;
snprintf(mfmt, sizeof(mfmt), "%snouveau %c[%8s][%s]%s %s", pfx,
name[level], nv_subdev(subdev)->name,
nv_device(device)->name, ofmt, fmt);
} else
if (object && nv_iclass(object, NV_CLIENT_CLASS)) {
if (level > nv_client(object)->debug)
return;
snprintf(mfmt, sizeof(mfmt), "%snouveau %c[%8s] %s", pfx,
name[level], nv_client(object)->name, fmt);
} else {
snprintf(mfmt, sizeof(mfmt), "%snouveau: %s", pfx, fmt);
}
va_start(args, fmt);
vprintk(mfmt, args);
va_end(args);
}

View File

@ -0,0 +1,108 @@
/*
* 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.
*/
#include <core/object.h>
#include <core/ramht.h>
#include <subdev/bar.h>
static u32
nouveau_ramht_hash(struct nouveau_ramht *ramht, int chid, u32 handle)
{
u32 hash = 0;
while (handle) {
hash ^= (handle & ((1 << ramht->bits) - 1));
handle >>= ramht->bits;
}
hash ^= chid << (ramht->bits - 4);
hash = hash << 3;
return hash;
}
int
nouveau_ramht_insert(struct nouveau_ramht *ramht, int chid,
u32 handle, u32 context)
{
struct nouveau_bar *bar = nouveau_bar(ramht);
u32 co, ho;
co = ho = nouveau_ramht_hash(ramht, chid, handle);
do {
if (!nv_ro32(ramht, co + 4)) {
nv_wo32(ramht, co + 0, handle);
nv_wo32(ramht, co + 4, context);
if (bar)
bar->flush(bar);
return co;
}
co += 8;
if (co >= nv_gpuobj(ramht)->size)
co = 0;
} while (co != ho);
return -ENOMEM;
}
void
nouveau_ramht_remove(struct nouveau_ramht *ramht, int cookie)
{
struct nouveau_bar *bar = nouveau_bar(ramht);
nv_wo32(ramht, cookie + 0, 0x00000000);
nv_wo32(ramht, cookie + 4, 0x00000000);
if (bar)
bar->flush(bar);
}
static struct nouveau_oclass
nouveau_ramht_oclass = {
.handle = 0x0000abcd,
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = NULL,
.dtor = _nouveau_gpuobj_dtor,
.init = _nouveau_gpuobj_init,
.fini = _nouveau_gpuobj_fini,
.rd32 = _nouveau_gpuobj_rd32,
.wr32 = _nouveau_gpuobj_wr32,
},
};
int
nouveau_ramht_new(struct nouveau_object *parent, struct nouveau_object *pargpu,
u32 size, u32 align, struct nouveau_ramht **pramht)
{
struct nouveau_ramht *ramht;
int ret;
ret = nouveau_gpuobj_create(parent, parent->engine ?
parent->engine : parent, /* <nv50 ramht */
&nouveau_ramht_oclass, 0, pargpu, size,
align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
*pramht = ramht;
if (ret)
return ret;
ramht->bits = order_base_2(nv_gpuobj(ramht)->size >> 3);
return 0;
}

View File

@ -0,0 +1,112 @@
/*
* 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/object.h>
#include <core/subdev.h>
#include <core/device.h>
#include <core/option.h>
void
nouveau_subdev_reset(struct nouveau_object *subdev)
{
nv_trace(subdev, "resetting...\n");
nv_ofuncs(subdev)->fini(subdev, false);
nv_debug(subdev, "reset\n");
}
int
nouveau_subdev_init(struct nouveau_subdev *subdev)
{
int ret = nouveau_object_init(&subdev->base);
if (ret)
return ret;
nouveau_subdev_reset(&subdev->base);
return 0;
}
int
_nouveau_subdev_init(struct nouveau_object *object)
{
return nouveau_subdev_init(nv_subdev(object));
}
int
nouveau_subdev_fini(struct nouveau_subdev *subdev, bool suspend)
{
if (subdev->unit) {
nv_mask(subdev, 0x000200, subdev->unit, 0x00000000);
nv_mask(subdev, 0x000200, subdev->unit, subdev->unit);
}
return nouveau_object_fini(&subdev->base, suspend);
}
int
_nouveau_subdev_fini(struct nouveau_object *object, bool suspend)
{
return nouveau_subdev_fini(nv_subdev(object), suspend);
}
void
nouveau_subdev_destroy(struct nouveau_subdev *subdev)
{
int subidx = nv_hclass(subdev) & 0xff;
nv_device(subdev)->subdev[subidx] = NULL;
nouveau_object_destroy(&subdev->base);
}
void
_nouveau_subdev_dtor(struct nouveau_object *object)
{
nouveau_subdev_destroy(nv_subdev(object));
}
int
nouveau_subdev_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, u32 pclass,
const char *subname, const char *sysname,
int size, void **pobject)
{
struct nouveau_subdev *subdev;
int ret;
ret = nouveau_object_create_(parent, engine, oclass, pclass |
NV_SUBDEV_CLASS, size, pobject);
subdev = *pobject;
if (ret)
return ret;
__mutex_init(&subdev->mutex, subname, &oclass->lock_class_key);
subdev->name = subname;
if (parent) {
struct nouveau_device *device = nv_device(parent);
subdev->debug = nouveau_dbgopt(device->dbgopt, subname);
subdev->mmio = nv_subdev(device)->mmio;
}
return 0;
}

View File

@ -0,0 +1,92 @@
/*
* 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, Ilia Mirkin
*/
#include <engine/xtensa.h>
#include <engine/bsp.h>
/*******************************************************************************
* BSP object classes
******************************************************************************/
static struct nouveau_oclass
nv84_bsp_sclass[] = {
{ 0x74b0, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* BSP context
******************************************************************************/
static struct nouveau_oclass
nv84_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_xtensa_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
nv84_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_xtensa *priv;
int ret;
ret = nouveau_xtensa_create(parent, engine, oclass, 0x103000, true,
"PBSP", "bsp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x04008000;
nv_engine(priv)->cclass = &nv84_bsp_cclass;
nv_engine(priv)->sclass = nv84_bsp_sclass;
priv->fifo_val = 0x1111;
priv->unkd28 = 0x90044;
return 0;
}
struct nouveau_oclass
nv84_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_bsp_ctor,
.dtor = _nouveau_xtensa_dtor,
.init = _nouveau_xtensa_init,
.fini = _nouveau_xtensa_fini,
.rd32 = _nouveau_xtensa_rd32,
.wr32 = _nouveau_xtensa_wr32,
},
};

View File

@ -0,0 +1,111 @@
/*
* 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, Maarten Lankhorst, Ilia Mirkin
*/
#include <engine/falcon.h>
#include <engine/bsp.h>
struct nv98_bsp_priv {
struct nouveau_falcon base;
};
/*******************************************************************************
* BSP object classes
******************************************************************************/
static struct nouveau_oclass
nv98_bsp_sclass[] = {
{ 0x88b1, &nouveau_object_ofuncs },
{ 0x85b1, &nouveau_object_ofuncs },
{ 0x86b1, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* PBSP context
******************************************************************************/
static struct nouveau_oclass
nv98_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0x98),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_falcon_context_ctor,
.dtor = _nouveau_falcon_context_dtor,
.init = _nouveau_falcon_context_init,
.fini = _nouveau_falcon_context_fini,
.rd32 = _nouveau_falcon_context_rd32,
.wr32 = _nouveau_falcon_context_wr32,
},
};
/*******************************************************************************
* PBSP engine/subdev functions
******************************************************************************/
static int
nv98_bsp_init(struct nouveau_object *object)
{
struct nv98_bsp_priv *priv = (void *)object;
int ret;
ret = nouveau_falcon_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x084010, 0x0000ffd2);
nv_wr32(priv, 0x08401c, 0x0000fff2);
return 0;
}
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_falcon_create(parent, engine, oclass, 0x084000, 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_falcon_dtor,
.init = nv98_bsp_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};

View File

@ -0,0 +1,110 @@
/*
* Copyright 2012 Maarten Lankhorst
*
* 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: Maarten Lankhorst
*/
#include <engine/falcon.h>
#include <engine/bsp.h>
struct nvc0_bsp_priv {
struct nouveau_falcon base;
};
/*******************************************************************************
* BSP object classes
******************************************************************************/
static struct nouveau_oclass
nvc0_bsp_sclass[] = {
{ 0x90b1, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* PBSP context
******************************************************************************/
static struct nouveau_oclass
nvc0_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_falcon_context_ctor,
.dtor = _nouveau_falcon_context_dtor,
.init = _nouveau_falcon_context_init,
.fini = _nouveau_falcon_context_fini,
.rd32 = _nouveau_falcon_context_rd32,
.wr32 = _nouveau_falcon_context_wr32,
},
};
/*******************************************************************************
* PBSP engine/subdev functions
******************************************************************************/
static int
nvc0_bsp_init(struct nouveau_object *object)
{
struct nvc0_bsp_priv *priv = (void *)object;
int ret;
ret = nouveau_falcon_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x084010, 0x0000fff2);
nv_wr32(priv, 0x08401c, 0x0000fff2);
return 0;
}
static int
nvc0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvc0_bsp_priv *priv;
int ret;
ret = nouveau_falcon_create(parent, engine, oclass, 0x084000, true,
"PBSP", "bsp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00008000;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nvc0_bsp_cclass;
nv_engine(priv)->sclass = nvc0_bsp_sclass;
return 0;
}
struct nouveau_oclass
nvc0_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_bsp_ctor,
.dtor = _nouveau_falcon_dtor,
.init = nvc0_bsp_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};

View File

@ -0,0 +1,110 @@
/*
* 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 <engine/falcon.h>
#include <engine/bsp.h>
struct nve0_bsp_priv {
struct nouveau_falcon base;
};
/*******************************************************************************
* BSP object classes
******************************************************************************/
static struct nouveau_oclass
nve0_bsp_sclass[] = {
{ 0x95b1, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* PBSP context
******************************************************************************/
static struct nouveau_oclass
nve0_bsp_cclass = {
.handle = NV_ENGCTX(BSP, 0xe0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_falcon_context_ctor,
.dtor = _nouveau_falcon_context_dtor,
.init = _nouveau_falcon_context_init,
.fini = _nouveau_falcon_context_fini,
.rd32 = _nouveau_falcon_context_rd32,
.wr32 = _nouveau_falcon_context_wr32,
},
};
/*******************************************************************************
* PBSP engine/subdev functions
******************************************************************************/
static int
nve0_bsp_init(struct nouveau_object *object)
{
struct nve0_bsp_priv *priv = (void *)object;
int ret;
ret = nouveau_falcon_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x084010, 0x0000fff2);
nv_wr32(priv, 0x08401c, 0x0000fff2);
return 0;
}
static int
nve0_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nve0_bsp_priv *priv;
int ret;
ret = nouveau_falcon_create(parent, engine, oclass, 0x084000, true,
"PBSP", "bsp", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00008000;
nv_subdev(priv)->intr = nouveau_falcon_intr;
nv_engine(priv)->cclass = &nve0_bsp_cclass;
nv_engine(priv)->sclass = nve0_bsp_sclass;
return 0;
}
struct nouveau_oclass
nve0_bsp_oclass = {
.handle = NV_ENGINE(BSP, 0xe0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_bsp_ctor,
.dtor = _nouveau_falcon_dtor,
.init = nve0_bsp_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};

View File

@ -0,0 +1,872 @@
/* fuc microcode for copy engine on nva3- chipsets
*
* 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
*/
/* To build for nva3:nvc0
* m4 -DNVA3 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nva3_copy.fuc.h
*
* To build for nvc0-
* m4 -DNVC0 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_copy.fuc.h
*/
ifdef(`NVA3',
.section #nva3_pcopy_data
,
.section #nvc0_pcopy_data
)
ctx_object: .b32 0
ifdef(`NVA3',
ctx_dma:
ctx_dma_query: .b32 0
ctx_dma_src: .b32 0
ctx_dma_dst: .b32 0
,)
.equ #ctx_dma_count 3
ctx_query_address_high: .b32 0
ctx_query_address_low: .b32 0
ctx_query_counter: .b32 0
ctx_src_address_high: .b32 0
ctx_src_address_low: .b32 0
ctx_src_pitch: .b32 0
ctx_src_tile_mode: .b32 0
ctx_src_xsize: .b32 0
ctx_src_ysize: .b32 0
ctx_src_zsize: .b32 0
ctx_src_zoff: .b32 0
ctx_src_xoff: .b32 0
ctx_src_yoff: .b32 0
ctx_src_cpp: .b32 0
ctx_dst_address_high: .b32 0
ctx_dst_address_low: .b32 0
ctx_dst_pitch: .b32 0
ctx_dst_tile_mode: .b32 0
ctx_dst_xsize: .b32 0
ctx_dst_ysize: .b32 0
ctx_dst_zsize: .b32 0
ctx_dst_zoff: .b32 0
ctx_dst_xoff: .b32 0
ctx_dst_yoff: .b32 0
ctx_dst_cpp: .b32 0
ctx_format: .b32 0
ctx_swz_const0: .b32 0
ctx_swz_const1: .b32 0
ctx_xcnt: .b32 0
ctx_ycnt: .b32 0
.align 256
dispatch_table:
// mthd 0x0000, NAME
.b16 0x000 1
.b32 #ctx_object ~0xffffffff
// mthd 0x0100, NOP
.b16 0x040 1
.b32 0x00010000 + #cmd_nop ~0xffffffff
// mthd 0x0140, PM_TRIGGER
.b16 0x050 1
.b32 0x00010000 + #cmd_pm_trigger ~0xffffffff
ifdef(`NVA3', `
// mthd 0x0180-0x018c, DMA_
.b16 0x060 #ctx_dma_count
dispatch_dma:
.b32 0x00010000 + #cmd_dma ~0xffffffff
.b32 0x00010000 + #cmd_dma ~0xffffffff
.b32 0x00010000 + #cmd_dma ~0xffffffff
',)
// mthd 0x0200-0x0218, SRC_TILE
.b16 0x80 7
.b32 #ctx_src_tile_mode ~0x00000fff
.b32 #ctx_src_xsize ~0x0007ffff
.b32 #ctx_src_ysize ~0x00001fff
.b32 #ctx_src_zsize ~0x000007ff
.b32 #ctx_src_zoff ~0x00000fff
.b32 #ctx_src_xoff ~0x0007ffff
.b32 #ctx_src_yoff ~0x00001fff
// mthd 0x0220-0x0238, DST_TILE
.b16 0x88 7
.b32 #ctx_dst_tile_mode ~0x00000fff
.b32 #ctx_dst_xsize ~0x0007ffff
.b32 #ctx_dst_ysize ~0x00001fff
.b32 #ctx_dst_zsize ~0x000007ff
.b32 #ctx_dst_zoff ~0x00000fff
.b32 #ctx_dst_xoff ~0x0007ffff
.b32 #ctx_dst_yoff ~0x00001fff
// mthd 0x0300-0x0304, EXEC, WRCACHE_FLUSH
.b16 0xc0 2
.b32 0x00010000 + #cmd_exec ~0xffffffff
.b32 0x00010000 + #cmd_wrcache_flush ~0xffffffff
// mthd 0x030c-0x0340, various stuff
.b16 0xc3 14
.b32 #ctx_src_address_high ~0x000000ff
.b32 #ctx_src_address_low ~0xffffffff
.b32 #ctx_dst_address_high ~0x000000ff
.b32 #ctx_dst_address_low ~0xffffffff
.b32 #ctx_src_pitch ~0x0007ffff
.b32 #ctx_dst_pitch ~0x0007ffff
.b32 #ctx_xcnt ~0x0000ffff
.b32 #ctx_ycnt ~0x00001fff
.b32 #ctx_format ~0x0333ffff
.b32 #ctx_swz_const0 ~0xffffffff
.b32 #ctx_swz_const1 ~0xffffffff
.b32 #ctx_query_address_high ~0x000000ff
.b32 #ctx_query_address_low ~0xffffffff
.b32 #ctx_query_counter ~0xffffffff
.b16 0x800 0
ifdef(`NVA3',
.section #nva3_pcopy_code
,
.section #nvc0_pcopy_code
)
main:
clear b32 $r0
mov $sp $r0
// setup i0 handler and route fifo and ctxswitch to it
mov $r1 #ih
mov $iv0 $r1
mov $r1 0x400
movw $r2 0xfff3
sethi $r2 0
iowr I[$r1 + 0x300] $r2
// enable interrupts
or $r2 0xc
iowr I[$r1] $r2
bset $flags ie0
// enable fifo access and context switching
mov $r1 0x1200
mov $r2 3
iowr I[$r1] $r2
// sleep forever, waking for interrupts
bset $flags $p0
spin:
sleep $p0
bra #spin
// i0 handler
ih:
iord $r1 I[$r0 + 0x200]
and $r2 $r1 0x00000008
bra e #ih_no_chsw
call #chsw
ih_no_chsw:
and $r2 $r1 0x00000004
bra e #ih_no_cmd
call #dispatch
ih_no_cmd:
and $r1 $r1 0x0000000c
iowr I[$r0 + 0x100] $r1
iret
// $p1 direction (0 = unload, 1 = load)
// $r3 channel
swctx:
mov $r4 0x7700
mov $xtargets $r4
ifdef(`NVA3', `
// target 7 hardcoded to ctx dma object
mov $xdbase $r0
', ` // NVC0
// read SCRATCH3 to decide if we are PCOPY0 or PCOPY1
mov $r4 0x2100
iord $r4 I[$r4 + 0]
and $r4 1
shl b32 $r4 4
add b32 $r4 0x30
// channel is in vram
mov $r15 0x61c
shl b32 $r15 6
mov $r5 0x114
iowrs I[$r15] $r5
// read 16-byte PCOPYn info, containing context pointer, from channel
shl b32 $r5 $r3 4
add b32 $r5 2
mov $xdbase $r5
mov $r5 $sp
// get a chunk of stack space, aligned to 256 byte boundary
sub b32 $r5 0x100
mov $r6 0xff
not b32 $r6
and $r5 $r6
sethi $r5 0x00020000
xdld $r4 $r5
xdwait
sethi $r5 0
// set context pointer, from within channel VM
mov $r14 0
iowrs I[$r15] $r14
ld b32 $r4 D[$r5 + 0]
shr b32 $r4 8
ld b32 $r6 D[$r5 + 4]
shl b32 $r6 24
or $r4 $r6
mov $xdbase $r4
')
// 256-byte context, at start of data segment
mov b32 $r4 $r0
sethi $r4 0x60000
// swap!
bra $p1 #swctx_load
xdst $r0 $r4
bra #swctx_done
swctx_load:
xdld $r0 $r4
swctx_done:
xdwait
ret
chsw:
// read current channel
mov $r2 0x1400
iord $r3 I[$r2]
// if it's active, unload it and return
xbit $r15 $r3 0x1e
bra e #chsw_no_unload
bclr $flags $p1
call #swctx
bclr $r3 0x1e
iowr I[$r2] $r3
mov $r4 1
iowr I[$r2 + 0x200] $r4
ret
// read next channel
chsw_no_unload:
iord $r3 I[$r2 + 0x100]
// is there a channel waiting to be loaded?
xbit $r13 $r3 0x1e
bra e #chsw_finish_load
bset $flags $p1
call #swctx
ifdef(`NVA3',
// load dma objects back into TARGET regs
mov $r5 #ctx_dma
mov $r6 #ctx_dma_count
chsw_load_ctx_dma:
ld b32 $r7 D[$r5 + $r6 * 4]
add b32 $r8 $r6 0x180
shl b32 $r8 8
iowr I[$r8] $r7
sub b32 $r6 1
bra nc #chsw_load_ctx_dma
,)
chsw_finish_load:
mov $r3 2
iowr I[$r2 + 0x200] $r3
ret
dispatch:
// read incoming fifo command
mov $r3 0x1900
iord $r2 I[$r3 + 0x100]
iord $r3 I[$r3 + 0x000]
and $r4 $r2 0x7ff
// $r2 will be used to store exception data
shl b32 $r2 0x10
// lookup method in the dispatch table, ILLEGAL_MTHD if not found
mov $r5 #dispatch_table
clear b32 $r6
clear b32 $r7
dispatch_loop:
ld b16 $r6 D[$r5 + 0]
ld b16 $r7 D[$r5 + 2]
add b32 $r5 4
cmpu b32 $r4 $r6
bra c #dispatch_illegal_mthd
add b32 $r7 $r6
cmpu b32 $r4 $r7
bra c #dispatch_valid_mthd
sub b32 $r7 $r6
shl b32 $r7 3
add b32 $r5 $r7
bra #dispatch_loop
// ensure no bits set in reserved fields, INVALID_BITFIELD
dispatch_valid_mthd:
sub b32 $r4 $r6
shl b32 $r4 3
add b32 $r4 $r5
ld b32 $r5 D[$r4 + 4]
and $r5 $r3
cmpu b32 $r5 0
bra ne #dispatch_invalid_bitfield
// depending on dispatch flags: execute method, or save data as state
ld b16 $r5 D[$r4 + 0]
ld b16 $r6 D[$r4 + 2]
cmpu b32 $r6 0
bra ne #dispatch_cmd
st b32 D[$r5] $r3
bra #dispatch_done
dispatch_cmd:
bclr $flags $p1
call $r5
bra $p1 #dispatch_error
bra #dispatch_done
dispatch_invalid_bitfield:
or $r2 2
dispatch_illegal_mthd:
or $r2 1
// store exception data in SCRATCH0/SCRATCH1, signal hostirq
dispatch_error:
mov $r4 0x1000
iowr I[$r4 + 0x000] $r2
iowr I[$r4 + 0x100] $r3
mov $r2 0x40
iowr I[$r0] $r2
hostirq_wait:
iord $r2 I[$r0 + 0x200]
and $r2 0x40
cmpu b32 $r2 0
bra ne #hostirq_wait
dispatch_done:
mov $r2 0x1d00
mov $r3 1
iowr I[$r2] $r3
ret
// No-operation
//
// Inputs:
// $r1: irqh state
// $r2: hostirq state
// $r3: data
// $r4: dispatch table entry
// Outputs:
// $r1: irqh state
// $p1: set on error
// $r2: hostirq state
// $r3: data
cmd_nop:
ret
// PM_TRIGGER
//
// Inputs:
// $r1: irqh state
// $r2: hostirq state
// $r3: data
// $r4: dispatch table entry
// Outputs:
// $r1: irqh state
// $p1: set on error
// $r2: hostirq state
// $r3: data
cmd_pm_trigger:
mov $r2 0x2200
clear b32 $r3
sethi $r3 0x20000
iowr I[$r2] $r3
ret
ifdef(`NVA3',
// SET_DMA_* method handler
//
// Inputs:
// $r1: irqh state
// $r2: hostirq state
// $r3: data
// $r4: dispatch table entry
// Outputs:
// $r1: irqh state
// $p1: set on error
// $r2: hostirq state
// $r3: data
cmd_dma:
sub b32 $r4 #dispatch_dma
shr b32 $r4 1
bset $r3 0x1e
st b32 D[$r4 + #ctx_dma] $r3
add b32 $r4 0x600
shl b32 $r4 6
iowr I[$r4] $r3
ret
,)
// Calculates the hw swizzle mask and adjusts the surface's xcnt to match
//
cmd_exec_set_format:
// zero out a chunk of the stack to store the swizzle into
add $sp -0x10
st b32 D[$sp + 0x00] $r0
st b32 D[$sp + 0x04] $r0
st b32 D[$sp + 0x08] $r0
st b32 D[$sp + 0x0c] $r0
// extract cpp, src_ncomp and dst_ncomp from FORMAT
ld b32 $r4 D[$r0 + #ctx_format]
extr $r5 $r4 16:17
add b32 $r5 1
extr $r6 $r4 20:21
add b32 $r6 1
extr $r7 $r4 24:25
add b32 $r7 1
// convert FORMAT swizzle mask to hw swizzle mask
bclr $flags $p2
clear b32 $r8
clear b32 $r9
ncomp_loop:
and $r10 $r4 0xf
shr b32 $r4 4
clear b32 $r11
bpc_loop:
cmpu b8 $r10 4
bra nc #cmp_c0
mulu $r12 $r10 $r5
add b32 $r12 $r11
bset $flags $p2
bra #bpc_next
cmp_c0:
bra ne #cmp_c1
mov $r12 0x10
add b32 $r12 $r11
bra #bpc_next
cmp_c1:
cmpu b8 $r10 6
bra nc #cmp_zero
mov $r12 0x14
add b32 $r12 $r11
bra #bpc_next
cmp_zero:
mov $r12 0x80
bpc_next:
st b8 D[$sp + $r8] $r12
add b32 $r8 1
add b32 $r11 1
cmpu b32 $r11 $r5
bra c #bpc_loop
add b32 $r9 1
cmpu b32 $r9 $r7
bra c #ncomp_loop
// SRC_XCNT = (xcnt * src_cpp), or 0 if no src ref in swz (hw will hang)
mulu $r6 $r5
st b32 D[$r0 + #ctx_src_cpp] $r6
ld b32 $r8 D[$r0 + #ctx_xcnt]
mulu $r6 $r8
bra $p2 #dst_xcnt
clear b32 $r6
dst_xcnt:
mulu $r7 $r5
st b32 D[$r0 + #ctx_dst_cpp] $r7
mulu $r7 $r8
mov $r5 0x810
shl b32 $r5 6
iowr I[$r5 + 0x000] $r6
iowr I[$r5 + 0x100] $r7
add b32 $r5 0x800
ld b32 $r6 D[$r0 + #ctx_dst_cpp]
sub b32 $r6 1
shl b32 $r6 8
ld b32 $r7 D[$r0 + #ctx_src_cpp]
sub b32 $r7 1
or $r6 $r7
iowr I[$r5 + 0x000] $r6
add b32 $r5 0x100
ld b32 $r6 D[$sp + 0x00]
iowr I[$r5 + 0x000] $r6
ld b32 $r6 D[$sp + 0x04]
iowr I[$r5 + 0x100] $r6
ld b32 $r6 D[$sp + 0x08]
iowr I[$r5 + 0x200] $r6
ld b32 $r6 D[$sp + 0x0c]
iowr I[$r5 + 0x300] $r6
add b32 $r5 0x400
ld b32 $r6 D[$r0 + #ctx_swz_const0]
iowr I[$r5 + 0x000] $r6
ld b32 $r6 D[$r0 + #ctx_swz_const1]
iowr I[$r5 + 0x100] $r6
add $sp 0x10
ret
// Setup to handle a tiled surface
//
// Calculates a number of parameters the hardware requires in order
// to correctly handle tiling.
//
// Offset calculation is performed as follows (Tp/Th/Td from TILE_MODE):
// nTx = round_up(w * cpp, 1 << Tp) >> Tp
// nTy = round_up(h, 1 << Th) >> Th
// Txo = (x * cpp) & ((1 << Tp) - 1)
// Tx = (x * cpp) >> Tp
// Tyo = y & ((1 << Th) - 1)
// Ty = y >> Th
// Tzo = z & ((1 << Td) - 1)
// Tz = z >> Td
//
// off = (Tzo << Tp << Th) + (Tyo << Tp) + Txo
// off += ((Tz * nTy * nTx)) + (Ty * nTx) + Tx) << Td << Th << Tp;
//
// Inputs:
// $r4: hw command (0x104800)
// $r5: ctx offset adjustment for src/dst selection
// $p2: set if dst surface
//
cmd_exec_set_surface_tiled:
// translate TILE_MODE into Tp, Th, Td shift values
ld b32 $r7 D[$r5 + #ctx_src_tile_mode]
extr $r9 $r7 8:11
extr $r8 $r7 4:7
ifdef(`NVA3',
add b32 $r8 2
,
add b32 $r8 3
)
extr $r7 $r7 0:3
cmp b32 $r7 0xe
bra ne #xtile64
mov $r7 4
bra #xtileok
xtile64:
xbit $r7 $flags $p2
add b32 $r7 17
bset $r4 $r7
mov $r7 6
xtileok:
// Op = (x * cpp) & ((1 << Tp) - 1)
// Tx = (x * cpp) >> Tp
ld b32 $r10 D[$r5 + #ctx_src_xoff]
ld b32 $r11 D[$r5 + #ctx_src_cpp]
mulu $r10 $r11
mov $r11 1
shl b32 $r11 $r7
sub b32 $r11 1
and $r12 $r10 $r11
shr b32 $r10 $r7
// Tyo = y & ((1 << Th) - 1)
// Ty = y >> Th
ld b32 $r13 D[$r5 + #ctx_src_yoff]
mov $r14 1
shl b32 $r14 $r8
sub b32 $r14 1
and $r11 $r13 $r14
shr b32 $r13 $r8
// YTILE = ((1 << Th) << 12) | ((1 << Th) - Tyo)
add b32 $r14 1
shl b32 $r15 $r14 12
sub b32 $r14 $r11
or $r15 $r14
xbit $r6 $flags $p2
add b32 $r6 0x208
shl b32 $r6 8
iowr I[$r6 + 0x000] $r15
// Op += Tyo << Tp
shl b32 $r11 $r7
add b32 $r12 $r11
// nTx = ((w * cpp) + ((1 << Tp) - 1) >> Tp)
ld b32 $r15 D[$r5 + #ctx_src_xsize]
ld b32 $r11 D[$r5 + #ctx_src_cpp]
mulu $r15 $r11
mov $r11 1
shl b32 $r11 $r7
sub b32 $r11 1
add b32 $r15 $r11
shr b32 $r15 $r7
push $r15
// nTy = (h + ((1 << Th) - 1)) >> Th
ld b32 $r15 D[$r5 + #ctx_src_ysize]
mov $r11 1
shl b32 $r11 $r8
sub b32 $r11 1
add b32 $r15 $r11
shr b32 $r15 $r8
push $r15
// Tys = Tp + Th
// CFG_YZ_TILE_SIZE = ((1 << Th) >> 2) << Td
add b32 $r7 $r8
sub b32 $r8 2
mov $r11 1
shl b32 $r11 $r8
shl b32 $r11 $r9
// Tzo = z & ((1 << Td) - 1)
// Tz = z >> Td
// Op += Tzo << Tys
// Ts = Tys + Td
ld b32 $r8 D[$r5 + #ctx_src_zoff]
mov $r14 1
shl b32 $r14 $r9
sub b32 $r14 1
and $r15 $r8 $r14
shl b32 $r15 $r7
add b32 $r12 $r15
add b32 $r7 $r9
shr b32 $r8 $r9
// Ot = ((Tz * nTy * nTx) + (Ty * nTx) + Tx) << Ts
pop $r15
pop $r9
mulu $r13 $r9
add b32 $r10 $r13
mulu $r8 $r9
mulu $r8 $r15
add b32 $r10 $r8
shl b32 $r10 $r7
// PITCH = (nTx - 1) << Ts
sub b32 $r9 1
shl b32 $r9 $r7
iowr I[$r6 + 0x200] $r9
// SRC_ADDRESS_LOW = (Ot + Op) & 0xffffffff
// CFG_ADDRESS_HIGH |= ((Ot + Op) >> 32) << 16
ld b32 $r7 D[$r5 + #ctx_src_address_low]
ld b32 $r8 D[$r5 + #ctx_src_address_high]
add b32 $r10 $r12
add b32 $r7 $r10
adc b32 $r8 0
shl b32 $r8 16
or $r8 $r11
sub b32 $r6 0x600
iowr I[$r6 + 0x000] $r7
add b32 $r6 0x400
iowr I[$r6 + 0x000] $r8
ret
// Setup to handle a linear surface
//
// Nothing to see here.. Sets ADDRESS and PITCH, pretty non-exciting
//
cmd_exec_set_surface_linear:
xbit $r6 $flags $p2
add b32 $r6 0x202
shl b32 $r6 8
ld b32 $r7 D[$r5 + #ctx_src_address_low]
iowr I[$r6 + 0x000] $r7
add b32 $r6 0x400
ld b32 $r7 D[$r5 + #ctx_src_address_high]
shl b32 $r7 16
iowr I[$r6 + 0x000] $r7
add b32 $r6 0x400
ld b32 $r7 D[$r5 + #ctx_src_pitch]
iowr I[$r6 + 0x000] $r7
ret
// wait for regs to be available for use
cmd_exec_wait:
push $r0
push $r1
mov $r0 0x800
shl b32 $r0 6
loop:
iord $r1 I[$r0]
and $r1 1
bra ne #loop
pop $r1
pop $r0
ret
cmd_exec_query:
// if QUERY_SHORT not set, write out { -, 0, TIME_LO, TIME_HI }
xbit $r4 $r3 13
bra ne #query_counter
call #cmd_exec_wait
mov $r4 0x80c
shl b32 $r4 6
ld b32 $r5 D[$r0 + #ctx_query_address_low]
add b32 $r5 4
iowr I[$r4 + 0x000] $r5
iowr I[$r4 + 0x100] $r0
mov $r5 0xc
iowr I[$r4 + 0x200] $r5
add b32 $r4 0x400
ld b32 $r5 D[$r0 + #ctx_query_address_high]
shl b32 $r5 16
iowr I[$r4 + 0x000] $r5
add b32 $r4 0x500
mov $r5 0x00000b00
sethi $r5 0x00010000
iowr I[$r4 + 0x000] $r5
mov $r5 0x00004040
shl b32 $r5 1
sethi $r5 0x80800000
iowr I[$r4 + 0x100] $r5
mov $r5 0x00001110
sethi $r5 0x13120000
iowr I[$r4 + 0x200] $r5
mov $r5 0x00001514
sethi $r5 0x17160000
iowr I[$r4 + 0x300] $r5
mov $r5 0x00002601
sethi $r5 0x00010000
mov $r4 0x800
shl b32 $r4 6
iowr I[$r4 + 0x000] $r5
// write COUNTER
query_counter:
call #cmd_exec_wait
mov $r4 0x80c
shl b32 $r4 6
ld b32 $r5 D[$r0 + #ctx_query_address_low]
iowr I[$r4 + 0x000] $r5
iowr I[$r4 + 0x100] $r0
mov $r5 0x4
iowr I[$r4 + 0x200] $r5
add b32 $r4 0x400
ld b32 $r5 D[$r0 + #ctx_query_address_high]
shl b32 $r5 16
iowr I[$r4 + 0x000] $r5
add b32 $r4 0x500
mov $r5 0x00000300
iowr I[$r4 + 0x000] $r5
mov $r5 0x00001110
sethi $r5 0x13120000
iowr I[$r4 + 0x100] $r5
ld b32 $r5 D[$r0 + #ctx_query_counter]
add b32 $r4 0x500
iowr I[$r4 + 0x000] $r5
mov $r5 0x00002601
sethi $r5 0x00010000
mov $r4 0x800
shl b32 $r4 6
iowr I[$r4 + 0x000] $r5
ret
// Execute a copy operation
//
// Inputs:
// $r1: irqh state
// $r2: hostirq state
// $r3: data
// 000002000 QUERY_SHORT
// 000001000 QUERY
// 000000100 DST_LINEAR
// 000000010 SRC_LINEAR
// 000000001 FORMAT
// $r4: dispatch table entry
// Outputs:
// $r1: irqh state
// $p1: set on error
// $r2: hostirq state
// $r3: data
cmd_exec:
call #cmd_exec_wait
// if format requested, call function to calculate it, otherwise
// fill in cpp/xcnt for both surfaces as if (cpp == 1)
xbit $r15 $r3 0
bra e #cmd_exec_no_format
call #cmd_exec_set_format
mov $r4 0x200
bra #cmd_exec_init_src_surface
cmd_exec_no_format:
mov $r6 0x810
shl b32 $r6 6
mov $r7 1
st b32 D[$r0 + #ctx_src_cpp] $r7
st b32 D[$r0 + #ctx_dst_cpp] $r7
ld b32 $r7 D[$r0 + #ctx_xcnt]
iowr I[$r6 + 0x000] $r7
iowr I[$r6 + 0x100] $r7
clear b32 $r4
cmd_exec_init_src_surface:
bclr $flags $p2
clear b32 $r5
xbit $r15 $r3 4
bra e #src_tiled
call #cmd_exec_set_surface_linear
bra #cmd_exec_init_dst_surface
src_tiled:
call #cmd_exec_set_surface_tiled
bset $r4 7
cmd_exec_init_dst_surface:
bset $flags $p2
mov $r5 #ctx_dst_address_high - #ctx_src_address_high
xbit $r15 $r3 8
bra e #dst_tiled
call #cmd_exec_set_surface_linear
bra #cmd_exec_kick
dst_tiled:
call #cmd_exec_set_surface_tiled
bset $r4 8
cmd_exec_kick:
mov $r5 0x800
shl b32 $r5 6
ld b32 $r6 D[$r0 + #ctx_ycnt]
iowr I[$r5 + 0x100] $r6
mov $r6 0x0041
// SRC_TARGET = 1, DST_TARGET = 2
sethi $r6 0x44000000
or $r4 $r6
iowr I[$r5] $r4
// if requested, queue up a QUERY write after the copy has completed
xbit $r15 $r3 12
bra e #cmd_exec_done
call #cmd_exec_query
cmd_exec_done:
ret
// Flush write cache
//
// Inputs:
// $r1: irqh state
// $r2: hostirq state
// $r3: data
// $r4: dispatch table entry
// Outputs:
// $r1: irqh state
// $p1: set on error
// $r2: hostirq state
// $r3: data
cmd_wrcache_flush:
mov $r2 0x2200
clear b32 $r3
sethi $r3 0x10000
iowr I[$r2] $r3
ret
.align 0x100

View File

@ -0,0 +1,620 @@
uint32_t nva3_pcopy_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_dma */
/* 0x0004: ctx_dma_query */
0x00000000,
/* 0x0008: ctx_dma_src */
0x00000000,
/* 0x000c: ctx_dma_dst */
0x00000000,
/* 0x0010: ctx_query_address_high */
0x00000000,
/* 0x0014: ctx_query_address_low */
0x00000000,
/* 0x0018: ctx_query_counter */
0x00000000,
/* 0x001c: ctx_src_address_high */
0x00000000,
/* 0x0020: ctx_src_address_low */
0x00000000,
/* 0x0024: ctx_src_pitch */
0x00000000,
/* 0x0028: ctx_src_tile_mode */
0x00000000,
/* 0x002c: ctx_src_xsize */
0x00000000,
/* 0x0030: ctx_src_ysize */
0x00000000,
/* 0x0034: ctx_src_zsize */
0x00000000,
/* 0x0038: ctx_src_zoff */
0x00000000,
/* 0x003c: ctx_src_xoff */
0x00000000,
/* 0x0040: ctx_src_yoff */
0x00000000,
/* 0x0044: ctx_src_cpp */
0x00000000,
/* 0x0048: ctx_dst_address_high */
0x00000000,
/* 0x004c: ctx_dst_address_low */
0x00000000,
/* 0x0050: ctx_dst_pitch */
0x00000000,
/* 0x0054: ctx_dst_tile_mode */
0x00000000,
/* 0x0058: ctx_dst_xsize */
0x00000000,
/* 0x005c: ctx_dst_ysize */
0x00000000,
/* 0x0060: ctx_dst_zsize */
0x00000000,
/* 0x0064: ctx_dst_zoff */
0x00000000,
/* 0x0068: ctx_dst_xoff */
0x00000000,
/* 0x006c: ctx_dst_yoff */
0x00000000,
/* 0x0070: ctx_dst_cpp */
0x00000000,
/* 0x0074: ctx_format */
0x00000000,
/* 0x0078: ctx_swz_const0 */
0x00000000,
/* 0x007c: ctx_swz_const1 */
0x00000000,
/* 0x0080: ctx_xcnt */
0x00000000,
/* 0x0084: ctx_ycnt */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* 0x0100: dispatch_table */
0x00010000,
0x00000000,
0x00000000,
0x00010040,
0x00010160,
0x00000000,
0x00010050,
0x00010162,
0x00000000,
0x00030060,
/* 0x0128: dispatch_dma */
0x00010170,
0x00000000,
0x00010170,
0x00000000,
0x00010170,
0x00000000,
0x00070080,
0x00000028,
0xfffff000,
0x0000002c,
0xfff80000,
0x00000030,
0xffffe000,
0x00000034,
0xfffff800,
0x00000038,
0xfffff000,
0x0000003c,
0xfff80000,
0x00000040,
0xffffe000,
0x00070088,
0x00000054,
0xfffff000,
0x00000058,
0xfff80000,
0x0000005c,
0xffffe000,
0x00000060,
0xfffff800,
0x00000064,
0xfffff000,
0x00000068,
0xfff80000,
0x0000006c,
0xffffe000,
0x000200c0,
0x00010492,
0x00000000,
0x0001051b,
0x00000000,
0x000e00c3,
0x0000001c,
0xffffff00,
0x00000020,
0x00000000,
0x00000048,
0xffffff00,
0x0000004c,
0x00000000,
0x00000024,
0xfff80000,
0x00000050,
0xfff80000,
0x00000080,
0xffff0000,
0x00000084,
0xffffe000,
0x00000074,
0xfccc0000,
0x00000078,
0x00000000,
0x0000007c,
0x00000000,
0x00000010,
0xffffff00,
0x00000014,
0x00000000,
0x00000018,
0x00000000,
0x00000800,
};
uint32_t nva3_pcopy_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
0xf10010fe,
0xf1040017,
0xf0fff327,
0x12d00023,
0x0c25f0c0,
0xf40012d0,
0x17f11031,
0x27f01200,
0x0012d003,
/* 0x002f: spin */
0xf40031f4,
0x0ef40028,
/* 0x0035: ih */
0x8001cffd,
0xf40812c4,
0x21f4060b,
/* 0x0041: ih_no_chsw */
0x0412c472,
0xf4060bf4,
/* 0x004a: ih_no_cmd */
0x11c4c321,
0x4001d00c,
/* 0x0052: swctx */
0x47f101f8,
0x4bfe7700,
0x0007fe00,
0xf00204b9,
0x01f40643,
0x0604fa09,
/* 0x006b: swctx_load */
0xfa060ef4,
/* 0x006e: swctx_done */
0x03f80504,
/* 0x0072: chsw */
0x27f100f8,
0x23cf1400,
0x1e3fc800,
0xf4170bf4,
0x21f40132,
0x1e3af052,
0xf00023d0,
0x24d00147,
/* 0x0093: chsw_no_unload */
0xcf00f880,
0x3dc84023,
0x220bf41e,
0xf40131f4,
0x57f05221,
0x0367f004,
/* 0x00a8: chsw_load_ctx_dma */
0xa07856bc,
0xb6018068,
0x87d00884,
0x0162b600,
/* 0x00bb: chsw_finish_load */
0xf0f018f4,
0x23d00237,
/* 0x00c3: dispatch */
0xf100f880,
0xcf190037,
0x33cf4032,
0xff24e400,
0x1024b607,
0x010057f1,
0x74bd64bd,
/* 0x00dc: dispatch_loop */
0x58005658,
0x50b60157,
0x0446b804,
0xbb4d08f4,
0x47b80076,
0x0f08f404,
0xb60276bb,
0x57bb0374,
0xdf0ef400,
/* 0x0100: dispatch_valid_mthd */
0xb60246bb,
0x45bb0344,
0x01459800,
0xb00453fd,
0x1bf40054,
0x00455820,
0xb0014658,
0x1bf40064,
0x00538009,
/* 0x0127: dispatch_cmd */
0xf4300ef4,
0x55f90132,
0xf40c01f4,
/* 0x0132: dispatch_invalid_bitfield */
0x25f0250e,
/* 0x0135: dispatch_illegal_mthd */
0x0125f002,
/* 0x0138: dispatch_error */
0x100047f1,
0xd00042d0,
0x27f04043,
0x0002d040,
/* 0x0148: hostirq_wait */
0xf08002cf,
0x24b04024,
0xf71bf400,
/* 0x0154: dispatch_done */
0x1d0027f1,
0xd00137f0,
0x00f80023,
/* 0x0160: cmd_nop */
/* 0x0162: cmd_pm_trigger */
0x27f100f8,
0x34bd2200,
0xd00233f0,
0x00f80023,
/* 0x0170: cmd_dma */
0x012842b7,
0xf00145b6,
0x43801e39,
0x0040b701,
0x0644b606,
0xf80043d0,
/* 0x0189: cmd_exec_set_format */
0xf030f400,
0xb00001b0,
0x01b00101,
0x0301b002,
0xc71d0498,
0x50b63045,
0x3446c701,
0xc70160b6,
0x70b63847,
0x0232f401,
0x94bd84bd,
/* 0x01b4: ncomp_loop */
0xb60f4ac4,
0xb4bd0445,
/* 0x01bc: bpc_loop */
0xf404a430,
0xa5ff0f18,
0x00cbbbc0,
0xf40231f4,
/* 0x01ce: cmp_c0 */
0x1bf4220e,
0x10c7f00c,
0xf400cbbb,
/* 0x01da: cmp_c1 */
0xa430160e,
0x0c18f406,
0xbb14c7f0,
0x0ef400cb,
/* 0x01e9: cmp_zero */
0x80c7f107,
/* 0x01ed: bpc_next */
0x01c83800,
0xb60180b6,
0xb5b801b0,
0xc308f404,
0xb80190b6,
0x08f40497,
0x0065fdb2,
0x98110680,
0x68fd2008,
0x0502f400,
/* 0x0216: dst_xcnt */
0x75fd64bd,
0x1c078000,
0xf10078fd,
0xb6081057,
0x56d00654,
0x4057d000,
0x080050b7,
0xb61c0698,
0x64b60162,
0x11079808,
0xfd0172b6,
0x56d00567,
0x0050b700,
0x0060b401,
0xb40056d0,
0x56d00160,
0x0260b440,
0xb48056d0,
0x56d00360,
0x0050b7c0,
0x1e069804,
0x980056d0,
0x56d01f06,
0x1030f440,
/* 0x0276: cmd_exec_set_surface_tiled */
0x579800f8,
0x6879c70a,
0xb66478c7,
0x77c70280,
0x0e76b060,
0xf0091bf4,
0x0ef40477,
/* 0x0291: xtile64 */
0x027cf00f,
0xfd1170b6,
0x77f00947,
/* 0x029d: xtileok */
0x0f5a9806,
0xfd115b98,
0xb7f000ab,
0x04b7bb01,
0xff01b2b6,
0xa7bbc4ab,
0x105d9805,
0xbb01e7f0,
0xe2b604e8,
0xb4deff01,
0xb605d8bb,
0xef9401e0,
0x02ebbb0c,
0xf005fefd,
0x60b7026c,
0x64b60208,
0x006fd008,
0xbb04b7bb,
0x5f9800cb,
0x115b980b,
0xf000fbfd,
0xb7bb01b7,
0x01b2b604,
0xbb00fbbb,
0xf0f905f7,
0xf00c5f98,
0xb8bb01b7,
0x01b2b604,
0xbb00fbbb,
0xf0f905f8,
0xb60078bb,
0xb7f00282,
0x04b8bb01,
0x9804b9bb,
0xe7f00e58,
0x04e9bb01,
0xff01e2b6,
0xf7bbf48e,
0x00cfbb04,
0xbb0079bb,
0xf0fc0589,
0xd9fd90fc,
0x00adbb00,
0xfd0089fd,
0xa8bb008f,
0x04a7bb00,
0xbb0192b6,
0x69d00497,
0x08579880,
0xbb075898,
0x7abb00ac,
0x0081b600,
0xfd1084b6,
0x62b7058b,
0x67d00600,
0x0060b700,
0x0068d004,
/* 0x0382: cmd_exec_set_surface_linear */
0x6cf000f8,
0x0260b702,
0x0864b602,
0xd0085798,
0x60b70067,
0x57980400,
0x1074b607,
0xb70067d0,
0x98040060,
0x67d00957,
/* 0x03ab: cmd_exec_wait */
0xf900f800,
0xf110f900,
0xb6080007,
/* 0x03b6: loop */
0x01cf0604,
0x0114f000,
0xfcfa1bf4,
0xf800fc10,
/* 0x03c5: cmd_exec_query */
0x0d34c800,
0xf5701bf4,
0xf103ab21,
0xb6080c47,
0x05980644,
0x0450b605,
0xd00045d0,
0x57f04040,
0x8045d00c,
0x040040b7,
0xb6040598,
0x45d01054,
0x0040b700,
0x0057f105,
0x0153f00b,
0xf10045d0,
0xb6404057,
0x53f10154,
0x45d08080,
0x1057f140,
0x1253f111,
0x8045d013,
0x151457f1,
0x171653f1,
0xf1c045d0,
0xf0260157,
0x47f10153,
0x44b60800,
0x0045d006,
/* 0x0438: query_counter */
0x03ab21f5,
0x080c47f1,
0x980644b6,
0x45d00505,
0x4040d000,
0xd00457f0,
0x40b78045,
0x05980400,
0x1054b604,
0xb70045d0,
0xf1050040,
0xd0030057,
0x57f10045,
0x53f11110,
0x45d01312,
0x06059840,
0x050040b7,
0xf10045d0,
0xf0260157,
0x47f10153,
0x44b60800,
0x0045d006,
/* 0x0492: cmd_exec */
0x21f500f8,
0x3fc803ab,
0x0e0bf400,
0x018921f5,
0x020047f1,
/* 0x04a7: cmd_exec_no_format */
0xf11e0ef4,
0xb6081067,
0x77f00664,
0x11078001,
0x981c0780,
0x67d02007,
0x4067d000,
/* 0x04c2: cmd_exec_init_src_surface */
0x32f444bd,
0xc854bd02,
0x0bf4043f,
0x8221f50a,
0x0a0ef403,
/* 0x04d4: src_tiled */
0x027621f5,
/* 0x04db: cmd_exec_init_dst_surface */
0xf40749f0,
0x57f00231,
0x083fc82c,
0xf50a0bf4,
0xf4038221,
/* 0x04ee: dst_tiled */
0x21f50a0e,
0x49f00276,
/* 0x04f5: cmd_exec_kick */
0x0057f108,
0x0654b608,
0xd0210698,
0x67f04056,
0x0063f141,
0x0546fd44,
0xc80054d0,
0x0bf40c3f,
0xc521f507,
/* 0x0519: cmd_exec_done */
/* 0x051b: cmd_wrcache_flush */
0xf100f803,
0xbd220027,
0x0133f034,
0xf80023d0,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};

View File

@ -0,0 +1,606 @@
uint32_t nvc0_pcopy_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_query_address_high */
0x00000000,
/* 0x0008: ctx_query_address_low */
0x00000000,
/* 0x000c: ctx_query_counter */
0x00000000,
/* 0x0010: ctx_src_address_high */
0x00000000,
/* 0x0014: ctx_src_address_low */
0x00000000,
/* 0x0018: ctx_src_pitch */
0x00000000,
/* 0x001c: ctx_src_tile_mode */
0x00000000,
/* 0x0020: ctx_src_xsize */
0x00000000,
/* 0x0024: ctx_src_ysize */
0x00000000,
/* 0x0028: ctx_src_zsize */
0x00000000,
/* 0x002c: ctx_src_zoff */
0x00000000,
/* 0x0030: ctx_src_xoff */
0x00000000,
/* 0x0034: ctx_src_yoff */
0x00000000,
/* 0x0038: ctx_src_cpp */
0x00000000,
/* 0x003c: ctx_dst_address_high */
0x00000000,
/* 0x0040: ctx_dst_address_low */
0x00000000,
/* 0x0044: ctx_dst_pitch */
0x00000000,
/* 0x0048: ctx_dst_tile_mode */
0x00000000,
/* 0x004c: ctx_dst_xsize */
0x00000000,
/* 0x0050: ctx_dst_ysize */
0x00000000,
/* 0x0054: ctx_dst_zsize */
0x00000000,
/* 0x0058: ctx_dst_zoff */
0x00000000,
/* 0x005c: ctx_dst_xoff */
0x00000000,
/* 0x0060: ctx_dst_yoff */
0x00000000,
/* 0x0064: ctx_dst_cpp */
0x00000000,
/* 0x0068: ctx_format */
0x00000000,
/* 0x006c: ctx_swz_const0 */
0x00000000,
/* 0x0070: ctx_swz_const1 */
0x00000000,
/* 0x0074: ctx_xcnt */
0x00000000,
/* 0x0078: ctx_ycnt */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* 0x0100: dispatch_table */
0x00010000,
0x00000000,
0x00000000,
0x00010040,
0x0001019f,
0x00000000,
0x00010050,
0x000101a1,
0x00000000,
0x00070080,
0x0000001c,
0xfffff000,
0x00000020,
0xfff80000,
0x00000024,
0xffffe000,
0x00000028,
0xfffff800,
0x0000002c,
0xfffff000,
0x00000030,
0xfff80000,
0x00000034,
0xffffe000,
0x00070088,
0x00000048,
0xfffff000,
0x0000004c,
0xfff80000,
0x00000050,
0xffffe000,
0x00000054,
0xfffff800,
0x00000058,
0xfffff000,
0x0000005c,
0xfff80000,
0x00000060,
0xffffe000,
0x000200c0,
0x000104b8,
0x00000000,
0x00010541,
0x00000000,
0x000e00c3,
0x00000010,
0xffffff00,
0x00000014,
0x00000000,
0x0000003c,
0xffffff00,
0x00000040,
0x00000000,
0x00000018,
0xfff80000,
0x00000044,
0xfff80000,
0x00000074,
0xffff0000,
0x00000078,
0xffffe000,
0x00000068,
0xfccc0000,
0x0000006c,
0x00000000,
0x00000070,
0x00000000,
0x00000004,
0xffffff00,
0x00000008,
0x00000000,
0x0000000c,
0x00000000,
0x00000800,
};
uint32_t nvc0_pcopy_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
0xf10010fe,
0xf1040017,
0xf0fff327,
0x12d00023,
0x0c25f0c0,
0xf40012d0,
0x17f11031,
0x27f01200,
0x0012d003,
/* 0x002f: spin */
0xf40031f4,
0x0ef40028,
/* 0x0035: ih */
0x8001cffd,
0xf40812c4,
0x21f4060b,
/* 0x0041: ih_no_chsw */
0x0412c4ca,
0xf5070bf4,
/* 0x004b: ih_no_cmd */
0xc4010221,
0x01d00c11,
/* 0x0053: swctx */
0xf101f840,
0xfe770047,
0x47f1004b,
0x44cf2100,
0x0144f000,
0xb60444b6,
0xf7f13040,
0xf4b6061c,
0x1457f106,
0x00f5d101,
0xb6043594,
0x57fe0250,
0x0145fe00,
0x010052b7,
0x00ff67f1,
0x56fd60bd,
0x0253f004,
0xf80545fa,
0x0053f003,
0xd100e7f0,
0x549800fe,
0x0845b600,
0xb6015698,
0x46fd1864,
0x0047fe05,
0xf00204b9,
0x01f40643,
0x0604fa09,
/* 0x00c3: swctx_load */
0xfa060ef4,
/* 0x00c6: swctx_done */
0x03f80504,
/* 0x00ca: chsw */
0x27f100f8,
0x23cf1400,
0x1e3fc800,
0xf4170bf4,
0x21f40132,
0x1e3af053,
0xf00023d0,
0x24d00147,
/* 0x00eb: chsw_no_unload */
0xcf00f880,
0x3dc84023,
0x090bf41e,
0xf40131f4,
/* 0x00fa: chsw_finish_load */
0x37f05321,
0x8023d002,
/* 0x0102: dispatch */
0x37f100f8,
0x32cf1900,
0x0033cf40,
0x07ff24e4,
0xf11024b6,
0xbd010057,
/* 0x011b: dispatch_loop */
0x5874bd64,
0x57580056,
0x0450b601,
0xf40446b8,
0x76bb4d08,
0x0447b800,
0xbb0f08f4,
0x74b60276,
0x0057bb03,
/* 0x013f: dispatch_valid_mthd */
0xbbdf0ef4,
0x44b60246,
0x0045bb03,
0xfd014598,
0x54b00453,
0x201bf400,
0x58004558,
0x64b00146,
0x091bf400,
0xf4005380,
/* 0x0166: dispatch_cmd */
0x32f4300e,
0xf455f901,
0x0ef40c01,
/* 0x0171: dispatch_invalid_bitfield */
0x0225f025,
/* 0x0174: dispatch_illegal_mthd */
/* 0x0177: dispatch_error */
0xf10125f0,
0xd0100047,
0x43d00042,
0x4027f040,
/* 0x0187: hostirq_wait */
0xcf0002d0,
0x24f08002,
0x0024b040,
/* 0x0193: dispatch_done */
0xf1f71bf4,
0xf01d0027,
0x23d00137,
/* 0x019f: cmd_nop */
0xf800f800,
/* 0x01a1: cmd_pm_trigger */
0x0027f100,
0xf034bd22,
0x23d00233,
/* 0x01af: cmd_exec_set_format */
0xf400f800,
0x01b0f030,
0x0101b000,
0xb00201b0,
0x04980301,
0x3045c71a,
0xc70150b6,
0x60b63446,
0x3847c701,
0xf40170b6,
0x84bd0232,
/* 0x01da: ncomp_loop */
0x4ac494bd,
0x0445b60f,
/* 0x01e2: bpc_loop */
0xa430b4bd,
0x0f18f404,
0xbbc0a5ff,
0x31f400cb,
0x220ef402,
/* 0x01f4: cmp_c0 */
0xf00c1bf4,
0xcbbb10c7,
0x160ef400,
/* 0x0200: cmp_c1 */
0xf406a430,
0xc7f00c18,
0x00cbbb14,
/* 0x020f: cmp_zero */
0xf1070ef4,
/* 0x0213: bpc_next */
0x380080c7,
0x80b601c8,
0x01b0b601,
0xf404b5b8,
0x90b6c308,
0x0497b801,
0xfdb208f4,
0x06800065,
0x1d08980e,
0xf40068fd,
0x64bd0502,
/* 0x023c: dst_xcnt */
0x800075fd,
0x78fd1907,
0x1057f100,
0x0654b608,
0xd00056d0,
0x50b74057,
0x06980800,
0x0162b619,
0x980864b6,
0x72b60e07,
0x0567fd01,
0xb70056d0,
0xb4010050,
0x56d00060,
0x0160b400,
0xb44056d0,
0x56d00260,
0x0360b480,
0xb7c056d0,
0x98040050,
0x56d01b06,
0x1c069800,
0xf44056d0,
0x00f81030,
/* 0x029c: cmd_exec_set_surface_tiled */
0xc7075798,
0x78c76879,
0x0380b664,
0xb06077c7,
0x1bf40e76,
0x0477f009,
/* 0x02b7: xtile64 */
0xf00f0ef4,
0x70b6027c,
0x0947fd11,
/* 0x02c3: xtileok */
0x980677f0,
0x5b980c5a,
0x00abfd0e,
0xbb01b7f0,
0xb2b604b7,
0xc4abff01,
0x9805a7bb,
0xe7f00d5d,
0x04e8bb01,
0xff01e2b6,
0xd8bbb4de,
0x01e0b605,
0xbb0cef94,
0xfefd02eb,
0x026cf005,
0x020860b7,
0xd00864b6,
0xb7bb006f,
0x00cbbb04,
0x98085f98,
0xfbfd0e5b,
0x01b7f000,
0xb604b7bb,
0xfbbb01b2,
0x05f7bb00,
0x5f98f0f9,
0x01b7f009,
0xb604b8bb,
0xfbbb01b2,
0x05f8bb00,
0x78bbf0f9,
0x0282b600,
0xbb01b7f0,
0xb9bb04b8,
0x0b589804,
0xbb01e7f0,
0xe2b604e9,
0xf48eff01,
0xbb04f7bb,
0x79bb00cf,
0x0589bb00,
0x90fcf0fc,
0xbb00d9fd,
0x89fd00ad,
0x008ffd00,
0xbb00a8bb,
0x92b604a7,
0x0497bb01,
0x988069d0,
0x58980557,
0x00acbb04,
0xb6007abb,
0x84b60081,
0x058bfd10,
0x060062b7,
0xb70067d0,
0xd0040060,
0x00f80068,
/* 0x03a8: cmd_exec_set_surface_linear */
0xb7026cf0,
0xb6020260,
0x57980864,
0x0067d005,
0x040060b7,
0xb6045798,
0x67d01074,
0x0060b700,
0x06579804,
0xf80067d0,
/* 0x03d1: cmd_exec_wait */
0xf900f900,
0x0007f110,
0x0604b608,
/* 0x03dc: loop */
0xf00001cf,
0x1bf40114,
0xfc10fcfa,
/* 0x03eb: cmd_exec_query */
0xc800f800,
0x1bf40d34,
0xd121f570,
0x0c47f103,
0x0644b608,
0xb6020598,
0x45d00450,
0x4040d000,
0xd00c57f0,
0x40b78045,
0x05980400,
0x1054b601,
0xb70045d0,
0xf1050040,
0xf00b0057,
0x45d00153,
0x4057f100,
0x0154b640,
0x808053f1,
0xf14045d0,
0xf1111057,
0xd0131253,
0x57f18045,
0x53f11514,
0x45d01716,
0x0157f1c0,
0x0153f026,
0x080047f1,
0xd00644b6,
/* 0x045e: query_counter */
0x21f50045,
0x47f103d1,
0x44b6080c,
0x02059806,
0xd00045d0,
0x57f04040,
0x8045d004,
0x040040b7,
0xb6010598,
0x45d01054,
0x0040b700,
0x0057f105,
0x0045d003,
0x111057f1,
0x131253f1,
0x984045d0,
0x40b70305,
0x45d00500,
0x0157f100,
0x0153f026,
0x080047f1,
0xd00644b6,
0x00f80045,
/* 0x04b8: cmd_exec */
0x03d121f5,
0xf4003fc8,
0x21f50e0b,
0x47f101af,
0x0ef40200,
/* 0x04cd: cmd_exec_no_format */
0x1067f11e,
0x0664b608,
0x800177f0,
0x07800e07,
0x1d079819,
0xd00067d0,
0x44bd4067,
/* 0x04e8: cmd_exec_init_src_surface */
0xbd0232f4,
0x043fc854,
0xf50a0bf4,
0xf403a821,
/* 0x04fa: src_tiled */
0x21f50a0e,
0x49f0029c,
/* 0x0501: cmd_exec_init_dst_surface */
0x0231f407,
0xc82c57f0,
0x0bf4083f,
0xa821f50a,
0x0a0ef403,
/* 0x0514: dst_tiled */
0x029c21f5,
/* 0x051b: cmd_exec_kick */
0xf10849f0,
0xb6080057,
0x06980654,
0x4056d01e,
0xf14167f0,
0xfd440063,
0x54d00546,
0x0c3fc800,
0xf5070bf4,
/* 0x053f: cmd_exec_done */
0xf803eb21,
/* 0x0541: cmd_wrcache_flush */
0x0027f100,
0xf034bd22,
0x23d00133,
0x0000f800,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};

View File

@ -0,0 +1,157 @@
/*
* 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 <engine/falcon.h>
#include <engine/fifo.h>
#include <engine/copy.h>
#include <subdev/fb.h>
#include <subdev/vm.h>
#include <core/client.h>
#include <core/class.h>
#include <core/enum.h>
#include "fuc/nva3.fuc.h"
struct nva3_copy_priv {
struct nouveau_falcon base;
};
/*******************************************************************************
* Copy object classes
******************************************************************************/
static struct nouveau_oclass
nva3_copy_sclass[] = {
{ 0x85b5, &nouveau_object_ofuncs },
{}
};
/*******************************************************************************
* PCOPY context
******************************************************************************/
static struct nouveau_oclass
nva3_copy_cclass = {
.handle = NV_ENGCTX(COPY0, 0xa3),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_falcon_context_ctor,
.dtor = _nouveau_falcon_context_dtor,
.init = _nouveau_falcon_context_init,
.fini = _nouveau_falcon_context_fini,
.rd32 = _nouveau_falcon_context_rd32,
.wr32 = _nouveau_falcon_context_wr32,
},
};
/*******************************************************************************
* PCOPY engine/subdev functions
******************************************************************************/
static const struct nouveau_enum nva3_copy_isr_error_name[] = {
{ 0x0001, "ILLEGAL_MTHD" },
{ 0x0002, "INVALID_ENUM" },
{ 0x0003, "INVALID_BITFIELD" },
{}
};
void
nva3_copy_intr(struct nouveau_subdev *subdev)
{
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
struct nouveau_engine *engine = nv_engine(subdev);
struct nouveau_falcon *falcon = (void *)subdev;
struct nouveau_object *engctx;
u32 dispatch = nv_ro32(falcon, 0x01c);
u32 stat = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16);
u64 inst = nv_ro32(falcon, 0x050) & 0x3fffffff;
u32 ssta = nv_ro32(falcon, 0x040) & 0x0000ffff;
u32 addr = nv_ro32(falcon, 0x040) >> 16;
u32 mthd = (addr & 0x07ff) << 2;
u32 subc = (addr & 0x3800) >> 11;
u32 data = nv_ro32(falcon, 0x044);
int chid;
engctx = nouveau_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x00000040) {
nv_error(falcon, "DISPATCH_ERROR [");
nouveau_enum_print(nva3_copy_isr_error_name, ssta);
pr_cont("] ch %d [0x%010llx %s] subc %d mthd 0x%04x data 0x%08x\n",
chid, inst << 12, nouveau_client_name(engctx), subc,
mthd, data);
nv_wo32(falcon, 0x004, 0x00000040);
stat &= ~0x00000040;
}
if (stat) {
nv_error(falcon, "unhandled intr 0x%08x\n", stat);
nv_wo32(falcon, 0x004, stat);
}
nouveau_engctx_put(engctx);
}
static int
nva3_copy_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
bool enable = (nv_device(parent)->chipset != 0xaf);
struct nva3_copy_priv *priv;
int ret;
ret = nouveau_falcon_create(parent, engine, oclass, 0x104000, enable,
"PCE0", "copy0", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00802000;
nv_subdev(priv)->intr = nva3_copy_intr;
nv_engine(priv)->cclass = &nva3_copy_cclass;
nv_engine(priv)->sclass = nva3_copy_sclass;
nv_falcon(priv)->code.data = nva3_pcopy_code;
nv_falcon(priv)->code.size = sizeof(nva3_pcopy_code);
nv_falcon(priv)->data.data = nva3_pcopy_data;
nv_falcon(priv)->data.size = sizeof(nva3_pcopy_data);
return 0;
}
struct nouveau_oclass
nva3_copy_oclass = {
.handle = NV_ENGINE(COPY0, 0xa3),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nva3_copy_ctor,
.dtor = _nouveau_falcon_dtor,
.init = _nouveau_falcon_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};

View File

@ -0,0 +1,174 @@
/*
* 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 <engine/falcon.h>
#include <engine/fifo.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"
struct nvc0_copy_priv {
struct nouveau_falcon base;
};
/*******************************************************************************
* Copy object classes
******************************************************************************/
static struct nouveau_oclass
nvc0_copy0_sclass[] = {
{ 0x90b5, &nouveau_object_ofuncs },
{},
};
static struct nouveau_oclass
nvc0_copy1_sclass[] = {
{ 0x90b8, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* PCOPY context
******************************************************************************/
static struct nouveau_ofuncs
nvc0_copy_context_ofuncs = {
.ctor = _nouveau_falcon_context_ctor,
.dtor = _nouveau_falcon_context_dtor,
.init = _nouveau_falcon_context_init,
.fini = _nouveau_falcon_context_fini,
.rd32 = _nouveau_falcon_context_rd32,
.wr32 = _nouveau_falcon_context_wr32,
};
static struct nouveau_oclass
nvc0_copy0_cclass = {
.handle = NV_ENGCTX(COPY0, 0xc0),
.ofuncs = &nvc0_copy_context_ofuncs,
};
static struct nouveau_oclass
nvc0_copy1_cclass = {
.handle = NV_ENGCTX(COPY1, 0xc0),
.ofuncs = &nvc0_copy_context_ofuncs,
};
/*******************************************************************************
* PCOPY engine/subdev functions
******************************************************************************/
static int
nvc0_copy_init(struct nouveau_object *object)
{
struct nvc0_copy_priv *priv = (void *)object;
int ret;
ret = nouveau_falcon_init(&priv->base);
if (ret)
return ret;
nv_wo32(priv, 0x084, nv_engidx(object) - NVDEV_ENGINE_COPY0);
return 0;
}
static int
nvc0_copy0_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvc0_copy_priv *priv;
int ret;
ret = nouveau_falcon_create(parent, engine, oclass, 0x104000, true,
"PCE0", "copy0", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000040;
nv_subdev(priv)->intr = nva3_copy_intr;
nv_engine(priv)->cclass = &nvc0_copy0_cclass;
nv_engine(priv)->sclass = nvc0_copy0_sclass;
nv_falcon(priv)->code.data = nvc0_pcopy_code;
nv_falcon(priv)->code.size = sizeof(nvc0_pcopy_code);
nv_falcon(priv)->data.data = nvc0_pcopy_data;
nv_falcon(priv)->data.size = sizeof(nvc0_pcopy_data);
return 0;
}
static int
nvc0_copy1_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvc0_copy_priv *priv;
int ret;
ret = nouveau_falcon_create(parent, engine, oclass, 0x105000, true,
"PCE1", "copy1", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000080;
nv_subdev(priv)->intr = nva3_copy_intr;
nv_engine(priv)->cclass = &nvc0_copy1_cclass;
nv_engine(priv)->sclass = nvc0_copy1_sclass;
nv_falcon(priv)->code.data = nvc0_pcopy_code;
nv_falcon(priv)->code.size = sizeof(nvc0_pcopy_code);
nv_falcon(priv)->data.data = nvc0_pcopy_data;
nv_falcon(priv)->data.size = sizeof(nvc0_pcopy_data);
return 0;
}
struct nouveau_oclass
nvc0_copy0_oclass = {
.handle = NV_ENGINE(COPY0, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_copy0_ctor,
.dtor = _nouveau_falcon_dtor,
.init = nvc0_copy_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};
struct nouveau_oclass
nvc0_copy1_oclass = {
.handle = NV_ENGINE(COPY1, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_copy1_ctor,
.dtor = _nouveau_falcon_dtor,
.init = nvc0_copy_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};

View File

@ -0,0 +1,177 @@
/*
* 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/os.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
#include <engine/copy.h>
struct nve0_copy_priv {
struct nouveau_engine base;
};
/*******************************************************************************
* Copy object classes
******************************************************************************/
static struct nouveau_oclass
nve0_copy_sclass[] = {
{ 0xa0b5, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* PCOPY context
******************************************************************************/
static struct nouveau_ofuncs
nve0_copy_context_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,
};
static struct nouveau_oclass
nve0_copy_cclass = {
.handle = NV_ENGCTX(COPY0, 0xc0),
.ofuncs = &nve0_copy_context_ofuncs,
};
/*******************************************************************************
* 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
nve0_copy0_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,
"PCE0", "copy0", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000040;
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_copy1_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,
"PCE1", "copy1", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
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)->sclass = nve0_copy_sclass;
return 0;
}
struct nouveau_oclass
nve0_copy0_oclass = {
.handle = NV_ENGINE(COPY0, 0xe0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_copy0_ctor,
.dtor = _nouveau_engine_dtor,
.init = _nouveau_engine_init,
.fini = _nouveau_engine_fini,
},
};
struct nouveau_oclass
nve0_copy1_oclass = {
.handle = NV_ENGINE(COPY1, 0xe0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_copy1_ctor,
.dtor = _nouveau_engine_dtor,
.init = _nouveau_engine_init,
.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,
},
};

View File

@ -0,0 +1,584 @@
uint32_t nv98_pcrypt_data[] = {
/* 0x0000: ctx_dma */
/* 0x0000: ctx_dma_query */
0x00000000,
/* 0x0004: ctx_dma_src */
0x00000000,
/* 0x0008: ctx_dma_dst */
0x00000000,
/* 0x000c: ctx_query_address_high */
0x00000000,
/* 0x0010: ctx_query_address_low */
0x00000000,
/* 0x0014: ctx_query_counter */
0x00000000,
/* 0x0018: ctx_cond_address_high */
0x00000000,
/* 0x001c: ctx_cond_address_low */
0x00000000,
/* 0x0020: ctx_cond_off */
0x00000000,
/* 0x0024: ctx_src_address_high */
0x00000000,
/* 0x0028: ctx_src_address_low */
0x00000000,
/* 0x002c: ctx_dst_address_high */
0x00000000,
/* 0x0030: ctx_dst_address_low */
0x00000000,
/* 0x0034: ctx_mode */
0x00000000,
0x00000000,
0x00000000,
/* 0x0040: ctx_key */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* 0x0050: ctx_iv */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* 0x0080: swap */
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
/* 0x00a0: common_cmd_dtable */
0x0002000c,
0xffffff00,
0x00020010,
0x0000000f,
0x00020014,
0x00000000,
0x00000192,
0xfffffffe,
0x00020018,
0xffffff00,
0x0002001c,
0x0000000f,
0x000001d7,
0xfffffff8,
0x00000260,
0xffffffff,
/* 0x00e0: engine_cmd_dtable */
0x00020040,
0x00000000,
0x00020044,
0x00000000,
0x00020048,
0x00000000,
0x0002004c,
0x00000000,
0x00020050,
0x00000000,
0x00020054,
0x00000000,
0x00020058,
0x00000000,
0x0002005c,
0x00000000,
0x00020024,
0xffffff00,
0x00020028,
0x0000000f,
0x0002002c,
0xffffff00,
0x00020030,
0x0000000f,
0x00000271,
0xfffffff0,
0x00010285,
0xf000000f,
/* 0x0150: crypt_dtable */
0x04db0321,
0x04b1032f,
0x04db0339,
0x04db034b,
0x04db0361,
0x04db0377,
0x04db0395,
0x04db03af,
0x04db03cd,
0x04db03e3,
0x04db03f9,
0x04db040f,
0x04830429,
0x0483043b,
0x0483045d,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};
uint32_t nv98_pcrypt_code[] = {
0x17f004bd,
0x0010fe35,
0xf10004fe,
0xf0fff017,
0x27f10013,
0x21d00400,
0x0c15f0c0,
0xf00021d0,
0x27f10317,
0x21d01200,
0x1031f400,
/* 0x002f: spin */
0xf40031f4,
0x0ef40028,
/* 0x0035: ih */
0x8001cffd,
0xb00812c4,
0x0bf40024,
0x0027f167,
0x002bfe77,
0xf00007fe,
0x23f00027,
0x0037f105,
0x0034cf14,
0xb0014594,
0x18f40055,
0x0602fa17,
0x4af003f8,
0x0034d01e,
0xd00147f0,
0x0ef48034,
/* 0x0075: ctxload */
0x4034cf33,
0xb0014f94,
0x18f400f5,
0x0502fa21,
0x57f003f8,
0x0267f000,
/* 0x008c: ctxload_dma_loop */
0xa07856bc,
0xb6018068,
0x87d00884,
0x0162b600,
/* 0x009f: dummyload */
0xf0f018f4,
0x35d00257,
/* 0x00a5: noctx */
0x0412c480,
0xf50024b0,
0xf100df0b,
0xcf190037,
0x33cf4032,
0xff24e400,
0x1024b607,
0x07bf45e4,
0xf50054b0,
0xf100b90b,
0xf1fae057,
0xb000ce67,
0x18f4c044,
0xa057f14d,
0x8867f1fc,
0x8044b000,
0xb03f18f4,
0x18f46044,
0x5044b019,
0xf1741bf4,
0xbd220027,
0x0233f034,
0xf50023d0,
/* 0x0103: dma_cmd */
0xb000810e,
0x18f46344,
0x0245945e,
0xfe8050b7,
0x801e39f0,
0x40b70053,
0x44b60120,
0x0043d008,
/* 0x0123: dtable_cmd */
0xb8600ef4,
0x18f40446,
0x0344b63e,
0x980045bb,
0x53fd0145,
0x0054b004,
0x58291bf4,
0x46580045,
0x0264b001,
0x98170bf4,
0x67fd0807,
0x0164b004,
0xf9300bf4,
0x0f01f455,
/* 0x015b: cmd_setctx */
0x80280ef4,
0x0ef40053,
/* 0x0161: invalid_bitfield */
0x0125f022,
/* 0x0164: dispatch_error */
/* 0x0164: illegal_mthd */
0x100047f1,
0xd00042d0,
0x47f04043,
0x0004d040,
/* 0x0174: im_loop */
0xf08004cf,
0x44b04044,
0xf71bf400,
/* 0x0180: cmddone */
0x1d0037f1,
0xd00147f0,
/* 0x018a: nocmd */
0x11c40034,
0x4001d00c,
/* 0x0192: cmd_query_get */
0x38f201f8,
0x0325f001,
0x0b0047f1,
/* 0x019c: ptimer_retry */
0xcf4046cf,
0x47cf0045,
0x0467b840,
0x98f41bf4,
0x04800504,
0x21008020,
0x80220580,
0x0bfe2306,
0x03049800,
0xfe1844b6,
0x04980047,
0x8057f104,
0x0253f000,
0xf80645fa,
/* 0x01d7: cmd_cond_mode */
0xf400f803,
0x25f00131,
0x0534b002,
0xf41218f4,
0x34b00132,
0x0b18f402,
0x800136f0,
/* 0x01f2: return */
0x00f80803,
/* 0x01f4: cmd_cond_mode_queryful */
0x98060498,
0x56c40705,
0x0855b6ff,
0xfd1844b6,
0x47fe0545,
0x000bfe00,
0x008057f1,
0xfa0253f0,
0x34b00565,
0x131bf402,
0x049803f8,
0x0044b021,
0x800b4cf0,
0x00f80804,
/* 0x022c: cmd_cond_mode_double */
0xb61060b6,
0x65fa1050,
0x9803f805,
0x06982005,
0x0456b824,
0x980b4cf0,
0x06982105,
0x0456b825,
0xfd0b5cf0,
0x34b00445,
0x0b5cf003,
0x800645fd,
0x00f80804,
/* 0x0260: cmd_wrcache_flush */
0xf10132f4,
0xbd220027,
0x0133f034,
0xf80023d0,
/* 0x0271: crypt_cmd_mode */
0x0131f400,
0xb00225f0,
0x18f40f34,
0x0132f409,
/* 0x0283: crypt_cmd_mode_return */
0xf80d0380,
/* 0x0285: crypt_cmd_length */
0x0034b000,
0xf4fb0bf4,
0x47f0033c,
0x0743f040,
0xf00604fa,
0x43f05047,
0x0604fa06,
0x3cf503f8,
0x47f1c407,
0x4bfe2100,
0x09049800,
0x950a0598,
0x44b60858,
0x0548fd18,
0x98ff55c4,
0x07980b06,
0x0878950c,
0xfd1864b6,
0x77c40568,
0x0d0898ff,
0x580284b6,
0x95f9a889,
0xf9a98958,
0x013cf495,
0x3cf403f8,
0xf803f861,
0x18489503,
0xbb084994,
0x81b60095,
0x09088000,
0x950a0980,
0x69941868,
0x0097bb08,
0x800081b6,
0x09800b08,
0x023cf40c,
0xf05047f0,
0x04fa0643,
0xf803f805,
/* 0x0321: crypt_copy_prep */
0x203cf500,
0x003cf594,
0x003cf588,
/* 0x032f: crypt_store_prep */
0xf500f88c,
0xf594103c,
0xf88c063c,
/* 0x0339: crypt_ecb_e_prep */
0x303cf500,
0x003cf594,
0x003cf588,
0x003cf5d0,
/* 0x034b: crypt_ecb_d_prep */
0xf500f88c,
0xf5c8773c,
0xf594303c,
0xf588003c,
0xf5d4003c,
0xf88c003c,
/* 0x0361: crypt_cbc_e_prep */
0x403cf500,
0x003cf594,
0x063cf588,
0x663cf5ac,
0x063cf5d0,
/* 0x0377: crypt_cbc_d_prep */
0xf500f88c,
0xf5c8773c,
0xf594503c,
0xf584623c,
0xf588063c,
0xf5d4603c,
0xf5ac203c,
0xf88c003c,
/* 0x0395: crypt_pcbc_e_prep */
0x503cf500,
0x003cf594,
0x063cf588,
0x663cf5ac,
0x063cf5d0,
0x063cf58c,
/* 0x03af: crypt_pcbc_d_prep */
0xf500f8ac,
0xf5c8773c,
0xf594503c,
0xf588003c,
0xf5d4013c,
0xf5ac163c,
0xf58c063c,
0xf8ac063c,
/* 0x03cd: crypt_cfb_e_prep */
0x403cf500,
0x663cf594,
0x003cf5d0,
0x063cf588,
0x063cf5ac,
/* 0x03e3: crypt_cfb_d_prep */
0xf500f88c,
0xf594403c,
0xf5d0603c,
0xf588063c,
0xf5ac603c,
0xf88c003c,
/* 0x03f9: crypt_ofb_prep */
0x403cf500,
0x663cf594,
0x003cf5d0,
0x603cf588,
0x003cf5ac,
/* 0x040f: crypt_ctr_prep */
0xf500f88c,
0xf594503c,
0xf5d0613c,
0xf5b0163c,
0xf588003c,
0xf5ac103c,
0xf88c003c,
/* 0x0429: crypt_cbc_mac_prep */
0x303cf500,
0x003cf594,
0x063cf588,
0x663cf5ac,
/* 0x043b: crypt_cmac_finish_complete_prep */
0xf500f8d0,
0xf594703c,
0xf588003c,
0xf5ac063c,
0xf5ac003c,
0xf5d0003c,
0xf5bc003c,
0xf5ac063c,
0xf8d0663c,
/* 0x045d: crypt_cmac_finish_partial_prep */
0x803cf500,
0x003cf594,
0x063cf588,
0x003cf5ac,
0x003cf5ac,
0x003cf5d0,
0x003cf5bc,
0x063cf5bc,
0x663cf5ac,
/* 0x0483: crypt_do_in */
0xbb00f8d0,
0x47fe0035,
0x8097f100,
0x0293f000,
/* 0x0490: crypt_do_in_loop */
0xf80559fa,
0x223cf403,
0xf50609fa,
0xf898103c,
0x1050b603,
0xf40453b8,
0x3cf4e91b,
0xf803f801,
/* 0x04b1: crypt_do_out */
0x0037bb00,
0xf10067fe,
0xf0008097,
/* 0x04be: crypt_do_out_loop */
0x3cf50293,
0x3cf49810,
0x0579fa61,
0xf40679fa,
0x03f8013c,
0xb81070b6,
0x1bf40473,
/* 0x04db: crypt_do_inout */
0xbb00f8e8,
0x97f10035,
0x93f00080,
/* 0x04e5: crypt_do_inout_loop */
0x0047fe02,
0xf80559fa,
0x213cf403,
0xf50609fa,
0xf498103c,
0x67fe613c,
0x0579fa00,
0xf40679fa,
0x03f8013c,
0xb61050b6,
0x53b81070,
0xd41bf404,
0x000000f8,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};

View File

@ -0,0 +1,189 @@
/*
* 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/client.h>
#include <core/os.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <engine/fifo.h>
#include <engine/crypt.h>
struct nv84_crypt_priv {
struct nouveau_engine base;
};
/*******************************************************************************
* Crypt object classes
******************************************************************************/
static int
nv84_crypt_object_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_gpuobj *obj;
int ret;
ret = nouveau_gpuobj_create(parent, engine, oclass, 0, parent,
16, 16, 0, &obj);
*pobject = nv_object(obj);
if (ret)
return ret;
nv_wo32(obj, 0x00, nv_mclass(obj));
nv_wo32(obj, 0x04, 0x00000000);
nv_wo32(obj, 0x08, 0x00000000);
nv_wo32(obj, 0x0c, 0x00000000);
return 0;
}
static struct nouveau_ofuncs
nv84_crypt_ofuncs = {
.ctor = nv84_crypt_object_ctor,
.dtor = _nouveau_gpuobj_dtor,
.init = _nouveau_gpuobj_init,
.fini = _nouveau_gpuobj_fini,
.rd32 = _nouveau_gpuobj_rd32,
.wr32 = _nouveau_gpuobj_wr32,
};
static struct nouveau_oclass
nv84_crypt_sclass[] = {
{ 0x74c1, &nv84_crypt_ofuncs },
{}
};
/*******************************************************************************
* PCRYPT context
******************************************************************************/
static struct nouveau_oclass
nv84_crypt_cclass = {
.handle = NV_ENGCTX(CRYPT, 0x84),
.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,
},
};
/*******************************************************************************
* PCRYPT engine/subdev functions
******************************************************************************/
static const struct nouveau_bitfield nv84_crypt_intr_mask[] = {
{ 0x00000001, "INVALID_STATE" },
{ 0x00000002, "ILLEGAL_MTHD" },
{ 0x00000004, "ILLEGAL_CLASS" },
{ 0x00000080, "QUERY" },
{ 0x00000100, "FAULT" },
{}
};
static void
nv84_crypt_intr(struct nouveau_subdev *subdev)
{
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
struct nouveau_engine *engine = nv_engine(subdev);
struct nouveau_object *engctx;
struct nv84_crypt_priv *priv = (void *)subdev;
u32 stat = nv_rd32(priv, 0x102130);
u32 mthd = nv_rd32(priv, 0x102190);
u32 data = nv_rd32(priv, 0x102194);
u32 inst = nv_rd32(priv, 0x102188) & 0x7fffffff;
int chid;
engctx = nouveau_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat) {
nv_error(priv, "%s", "");
nouveau_bitfield_print(nv84_crypt_intr_mask, stat);
pr_cont(" ch %d [0x%010llx %s] mthd 0x%04x data 0x%08x\n",
chid, (u64)inst << 12, nouveau_client_name(engctx),
mthd, data);
}
nv_wr32(priv, 0x102130, stat);
nv_wr32(priv, 0x10200c, 0x10);
nouveau_engctx_put(engctx);
}
static int
nv84_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv84_crypt_priv *priv;
int ret;
ret = nouveau_engine_create(parent, engine, oclass, true,
"PCRYPT", "crypt", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00004000;
nv_subdev(priv)->intr = nv84_crypt_intr;
nv_engine(priv)->cclass = &nv84_crypt_cclass;
nv_engine(priv)->sclass = nv84_crypt_sclass;
return 0;
}
static int
nv84_crypt_init(struct nouveau_object *object)
{
struct nv84_crypt_priv *priv = (void *)object;
int ret;
ret = nouveau_engine_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x102130, 0xffffffff);
nv_wr32(priv, 0x102140, 0xffffffbf);
nv_wr32(priv, 0x10200c, 0x00000010);
return 0;
}
struct nouveau_oclass
nv84_crypt_oclass = {
.handle = NV_ENGINE(CRYPT, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_crypt_ctor,
.dtor = _nouveau_engine_dtor,
.init = nv84_crypt_init,
.fini = _nouveau_engine_fini,
},
};

View File

@ -0,0 +1,157 @@
/*
* 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/client.h>
#include <core/os.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <engine/falcon.h>
#include <engine/fifo.h>
#include <engine/crypt.h>
#include "fuc/nv98.fuc.h"
struct nv98_crypt_priv {
struct nouveau_falcon base;
};
/*******************************************************************************
* Crypt object classes
******************************************************************************/
static struct nouveau_oclass
nv98_crypt_sclass[] = {
{ 0x88b4, &nouveau_object_ofuncs },
{},
};
/*******************************************************************************
* PCRYPT context
******************************************************************************/
static struct nouveau_oclass
nv98_crypt_cclass = {
.handle = NV_ENGCTX(CRYPT, 0x98),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = _nouveau_falcon_context_ctor,
.dtor = _nouveau_falcon_context_dtor,
.init = _nouveau_falcon_context_init,
.fini = _nouveau_falcon_context_fini,
.rd32 = _nouveau_falcon_context_rd32,
.wr32 = _nouveau_falcon_context_wr32,
},
};
/*******************************************************************************
* PCRYPT engine/subdev functions
******************************************************************************/
static const struct nouveau_enum nv98_crypt_isr_error_name[] = {
{ 0x0000, "ILLEGAL_MTHD" },
{ 0x0001, "INVALID_BITFIELD" },
{ 0x0002, "INVALID_ENUM" },
{ 0x0003, "QUERY" },
{}
};
static void
nv98_crypt_intr(struct nouveau_subdev *subdev)
{
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
struct nouveau_engine *engine = nv_engine(subdev);
struct nouveau_object *engctx;
struct nv98_crypt_priv *priv = (void *)subdev;
u32 disp = nv_rd32(priv, 0x08701c);
u32 stat = nv_rd32(priv, 0x087008) & disp & ~(disp >> 16);
u32 inst = nv_rd32(priv, 0x087050) & 0x3fffffff;
u32 ssta = nv_rd32(priv, 0x087040) & 0x0000ffff;
u32 addr = nv_rd32(priv, 0x087040) >> 16;
u32 mthd = (addr & 0x07ff) << 2;
u32 subc = (addr & 0x3800) >> 11;
u32 data = nv_rd32(priv, 0x087044);
int chid;
engctx = nouveau_engctx_get(engine, inst);
chid = pfifo->chid(pfifo, engctx);
if (stat & 0x00000040) {
nv_error(priv, "DISPATCH_ERROR [");
nouveau_enum_print(nv98_crypt_isr_error_name, ssta);
pr_cont("] ch %d [0x%010llx %s] subc %d mthd 0x%04x data 0x%08x\n",
chid, (u64)inst << 12, nouveau_client_name(engctx),
subc, mthd, data);
nv_wr32(priv, 0x087004, 0x00000040);
stat &= ~0x00000040;
}
if (stat) {
nv_error(priv, "unhandled intr 0x%08x\n", stat);
nv_wr32(priv, 0x087004, stat);
}
nouveau_engctx_put(engctx);
}
static int
nv98_crypt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv98_crypt_priv *priv;
int ret;
ret = nouveau_falcon_create(parent, engine, oclass, 0x087000, true,
"PCRYPT", "crypt", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00004000;
nv_subdev(priv)->intr = nv98_crypt_intr;
nv_engine(priv)->cclass = &nv98_crypt_cclass;
nv_engine(priv)->sclass = nv98_crypt_sclass;
nv_falcon(priv)->code.data = nv98_pcrypt_code;
nv_falcon(priv)->code.size = sizeof(nv98_pcrypt_code);
nv_falcon(priv)->data.data = nv98_pcrypt_data;
nv_falcon(priv)->data.size = sizeof(nv98_pcrypt_data);
return 0;
}
struct nouveau_oclass
nv98_crypt_oclass = {
.handle = NV_ENGINE(CRYPT, 0x98),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv98_crypt_ctor,
.dtor = _nouveau_falcon_dtor,
.init = _nouveau_falcon_init,
.fini = _nouveau_falcon_fini,
.rd32 = _nouveau_falcon_rd32,
.wr32 = _nouveau_falcon_wr32,
},
};

View File

@ -0,0 +1,566 @@
/*
* 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/object.h>
#include <core/device.h>
#include <core/client.h>
#include <core/option.h>
#include <core/class.h>
#include "priv.h"
static DEFINE_MUTEX(nv_devices_mutex);
static LIST_HEAD(nv_devices);
struct nouveau_device *
nouveau_device_find(u64 name)
{
struct nouveau_device *device, *match = NULL;
mutex_lock(&nv_devices_mutex);
list_for_each_entry(device, &nv_devices, head) {
if (device->handle == name) {
match = device;
break;
}
}
mutex_unlock(&nv_devices_mutex);
return match;
}
/******************************************************************************
* nouveau_devobj (0x0080): class implementation
*****************************************************************************/
struct nouveau_devobj {
struct nouveau_parent base;
struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
};
static const u64 disable_map[] = {
[NVDEV_SUBDEV_VBIOS] = NV_DEVICE_DISABLE_VBIOS,
[NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_GPIO] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_I2C] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_CLOCK] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_MXM] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_MC] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_BUS] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_TIMER] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_FB] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_LTCG] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_IBUS] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_VM] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE,
[NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE,
[NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE,
[NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE,
[NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO,
[NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO,
[NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH,
[NVDEV_ENGINE_MPEG] = NV_DEVICE_DISABLE_MPEG,
[NVDEV_ENGINE_ME] = NV_DEVICE_DISABLE_ME,
[NVDEV_ENGINE_VP] = NV_DEVICE_DISABLE_VP,
[NVDEV_ENGINE_CRYPT] = NV_DEVICE_DISABLE_CRYPT,
[NVDEV_ENGINE_BSP] = NV_DEVICE_DISABLE_BSP,
[NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP,
[NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0,
[NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1,
[NVDEV_ENGINE_VIC] = NV_DEVICE_DISABLE_VIC,
[NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC,
[NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP,
[NVDEV_SUBDEV_NR] = 0,
};
static int
nouveau_devobj_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_client *client = nv_client(parent);
struct nouveau_device *device;
struct nouveau_devobj *devobj;
struct nv_device_class *args = data;
u32 boot0, strap;
u64 disable, mmio_base, mmio_size;
void __iomem *map;
int ret, i, c;
if (size < sizeof(struct nv_device_class))
return -EINVAL;
/* find the device subdev that matches what the client requested */
device = nv_device(client->device);
if (args->device != ~0) {
device = nouveau_device_find(args->device);
if (!device)
return -ENODEV;
}
ret = nouveau_parent_create(parent, nv_object(device), oclass, 0,
nouveau_control_oclass,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_FIFO) |
(1ULL << NVDEV_ENGINE_DISP) |
(1ULL << NVDEV_ENGINE_PERFMON), &devobj);
*pobject = nv_object(devobj);
if (ret)
return ret;
mmio_base = nv_device_resource_start(device, 0);
mmio_size = nv_device_resource_len(device, 0);
/* translate api disable mask into internal mapping */
disable = args->debug0;
for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
if (args->disable & disable_map[i])
disable |= (1ULL << i);
}
/* identify the chipset, and determine classes of subdev/engines */
if (!(args->disable & NV_DEVICE_DISABLE_IDENTIFY) &&
!device->card_type) {
map = ioremap(mmio_base, 0x102000);
if (map == NULL)
return -ENOMEM;
/* switch mmio to cpu's native endianness */
#ifndef __BIG_ENDIAN
if (ioread32_native(map + 0x000004) != 0x00000000)
#else
if (ioread32_native(map + 0x000004) == 0x00000000)
#endif
iowrite32_native(0x01000001, map + 0x000004);
/* read boot0 and strapping information */
boot0 = ioread32_native(map + 0x000000);
strap = ioread32_native(map + 0x101000);
iounmap(map);
/* determine chipset and derive architecture from it */
if ((boot0 & 0x1f000000) > 0) {
device->chipset = (boot0 & 0x1ff00000) >> 20;
switch (device->chipset & 0x1f0) {
case 0x010: {
if (0x461 & (1 << (device->chipset & 0xf)))
device->card_type = NV_10;
else
device->card_type = NV_11;
break;
}
case 0x020: device->card_type = NV_20; break;
case 0x030: device->card_type = NV_30; break;
case 0x040:
case 0x060: device->card_type = NV_40; break;
case 0x050:
case 0x080:
case 0x090:
case 0x0a0: device->card_type = NV_50; break;
case 0x0c0: device->card_type = NV_C0; break;
case 0x0d0: device->card_type = NV_D0; break;
case 0x0e0:
case 0x0f0:
case 0x100: device->card_type = NV_E0; break;
case 0x110: device->card_type = GM100; break;
default:
break;
}
} else
if ((boot0 & 0xff00fff0) == 0x20004000) {
if (boot0 & 0x00f00000)
device->chipset = 0x05;
else
device->chipset = 0x04;
device->card_type = NV_04;
}
switch (device->card_type) {
case NV_04: ret = nv04_identify(device); break;
case NV_10:
case NV_11: ret = nv10_identify(device); break;
case NV_20: ret = nv20_identify(device); break;
case NV_30: ret = nv30_identify(device); break;
case NV_40: ret = nv40_identify(device); break;
case NV_50: ret = nv50_identify(device); break;
case NV_C0:
case NV_D0: ret = nvc0_identify(device); break;
case NV_E0: ret = nve0_identify(device); break;
case GM100: ret = gm100_identify(device); break;
default:
ret = -EINVAL;
break;
}
if (ret) {
nv_error(device, "unknown chipset, 0x%08x\n", boot0);
return ret;
}
nv_info(device, "BOOT0 : 0x%08x\n", boot0);
nv_info(device, "Chipset: %s (NV%02X)\n",
device->cname, device->chipset);
nv_info(device, "Family : NV%02X\n", device->card_type);
/* determine frequency of timing crystal */
if ( device->card_type <= NV_10 || device->chipset < 0x17 ||
(device->chipset >= 0x20 && device->chipset < 0x25))
strap &= 0x00000040;
else
strap &= 0x00400040;
switch (strap) {
case 0x00000000: device->crystal = 13500; break;
case 0x00000040: device->crystal = 14318; break;
case 0x00400000: device->crystal = 27000; break;
case 0x00400040: device->crystal = 25000; break;
}
nv_debug(device, "crystal freq: %dKHz\n", device->crystal);
}
if (!(args->disable & NV_DEVICE_DISABLE_MMIO) &&
!nv_subdev(device)->mmio) {
nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size);
if (!nv_subdev(device)->mmio) {
nv_error(device, "unable to map device registers\n");
return -ENOMEM;
}
}
/* ensure requested subsystems are available for use */
for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) {
if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
continue;
if (device->subdev[i]) {
nouveau_object_ref(device->subdev[i],
&devobj->subdev[i]);
continue;
}
ret = nouveau_object_ctor(nv_object(device), NULL,
oclass, NULL, i,
&devobj->subdev[i]);
if (ret == -ENODEV)
continue;
if (ret)
return ret;
device->subdev[i] = devobj->subdev[i];
/* note: can't init *any* subdevs until devinit has been run
* due to not knowing exactly what the vbios init tables will
* mess with. devinit also can't be run until all of its
* dependencies have been created.
*
* this code delays init of any subdev until all of devinit's
* dependencies have been created, and then initialises each
* subdev in turn as they're created.
*/
while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) {
struct nouveau_object *subdev = devobj->subdev[c++];
if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) {
ret = nouveau_object_inc(subdev);
if (ret)
return ret;
atomic_dec(&nv_object(device)->usecount);
} else
if (subdev) {
nouveau_subdev_reset(subdev);
}
}
}
return 0;
}
static void
nouveau_devobj_dtor(struct nouveau_object *object)
{
struct nouveau_devobj *devobj = (void *)object;
int i;
for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--)
nouveau_object_ref(NULL, &devobj->subdev[i]);
nouveau_parent_destroy(&devobj->base);
}
static u8
nouveau_devobj_rd08(struct nouveau_object *object, u64 addr)
{
return nv_rd08(object->engine, addr);
}
static u16
nouveau_devobj_rd16(struct nouveau_object *object, u64 addr)
{
return nv_rd16(object->engine, addr);
}
static u32
nouveau_devobj_rd32(struct nouveau_object *object, u64 addr)
{
return nv_rd32(object->engine, addr);
}
static void
nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data)
{
nv_wr08(object->engine, addr, data);
}
static void
nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data)
{
nv_wr16(object->engine, addr, data);
}
static void
nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data)
{
nv_wr32(object->engine, addr, data);
}
static struct nouveau_ofuncs
nouveau_devobj_ofuncs = {
.ctor = nouveau_devobj_ctor,
.dtor = nouveau_devobj_dtor,
.init = _nouveau_parent_init,
.fini = _nouveau_parent_fini,
.rd08 = nouveau_devobj_rd08,
.rd16 = nouveau_devobj_rd16,
.rd32 = nouveau_devobj_rd32,
.wr08 = nouveau_devobj_wr08,
.wr16 = nouveau_devobj_wr16,
.wr32 = nouveau_devobj_wr32,
};
/******************************************************************************
* nouveau_device: engine functions
*****************************************************************************/
static struct nouveau_oclass
nouveau_device_sclass[] = {
{ 0x0080, &nouveau_devobj_ofuncs },
{}
};
static int
nouveau_device_fini(struct nouveau_object *object, bool suspend)
{
struct nouveau_device *device = (void *)object;
struct nouveau_object *subdev;
int ret, i;
for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
ret = nouveau_object_dec(subdev, suspend);
if (ret && suspend)
goto fail;
}
}
}
ret = 0;
fail:
for (; ret && i < NVDEV_SUBDEV_NR; i++) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
ret = nouveau_object_inc(subdev);
if (ret) {
/* XXX */
}
}
}
}
return ret;
}
static int
nouveau_device_init(struct nouveau_object *object)
{
struct nouveau_device *device = (void *)object;
struct nouveau_object *subdev;
int ret, i;
for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
ret = nouveau_object_inc(subdev);
if (ret)
goto fail;
} else {
nouveau_subdev_reset(subdev);
}
}
}
ret = 0;
fail:
for (--i; ret && i >= 0; i--) {
if ((subdev = device->subdev[i])) {
if (!nv_iclass(subdev, NV_ENGINE_CLASS))
nouveau_object_dec(subdev, false);
}
}
return ret;
}
static void
nouveau_device_dtor(struct nouveau_object *object)
{
struct nouveau_device *device = (void *)object;
mutex_lock(&nv_devices_mutex);
list_del(&device->head);
mutex_unlock(&nv_devices_mutex);
if (nv_subdev(device)->mmio)
iounmap(nv_subdev(device)->mmio);
nouveau_engine_destroy(&device->base);
}
resource_size_t
nv_device_resource_start(struct nouveau_device *device, unsigned int bar)
{
if (nv_device_is_pci(device)) {
return pci_resource_start(device->pdev, bar);
} else {
struct resource *res;
res = platform_get_resource(device->platformdev,
IORESOURCE_MEM, bar);
if (!res)
return 0;
return res->start;
}
}
resource_size_t
nv_device_resource_len(struct nouveau_device *device, unsigned int bar)
{
if (nv_device_is_pci(device)) {
return pci_resource_len(device->pdev, bar);
} else {
struct resource *res;
res = platform_get_resource(device->platformdev,
IORESOURCE_MEM, bar);
if (!res)
return 0;
return resource_size(res);
}
}
dma_addr_t
nv_device_map_page(struct nouveau_device *device, struct page *page)
{
dma_addr_t ret;
if (nv_device_is_pci(device)) {
ret = pci_map_page(device->pdev, page, 0, PAGE_SIZE,
PCI_DMA_BIDIRECTIONAL);
if (pci_dma_mapping_error(device->pdev, ret))
ret = 0;
} else {
ret = page_to_phys(page);
}
return ret;
}
void
nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr)
{
if (nv_device_is_pci(device))
pci_unmap_page(device->pdev, addr, PAGE_SIZE,
PCI_DMA_BIDIRECTIONAL);
}
int
nv_device_get_irq(struct nouveau_device *device, bool stall)
{
if (nv_device_is_pci(device)) {
return device->pdev->irq;
} else {
return platform_get_irq_byname(device->platformdev,
stall ? "stall" : "nonstall");
}
}
static struct nouveau_oclass
nouveau_device_oclass = {
.handle = NV_ENGINE(DEVICE, 0x00),
.ofuncs = &(struct nouveau_ofuncs) {
.dtor = nouveau_device_dtor,
.init = nouveau_device_init,
.fini = nouveau_device_fini,
},
};
int
nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name,
const char *sname, const char *cfg, const char *dbg,
int length, void **pobject)
{
struct nouveau_device *device;
int ret = -EEXIST;
mutex_lock(&nv_devices_mutex);
list_for_each_entry(device, &nv_devices, head) {
if (device->handle == name)
goto done;
}
ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true,
"DEVICE", "device", length, pobject);
device = *pobject;
if (ret)
goto done;
switch (type) {
case NOUVEAU_BUS_PCI:
device->pdev = dev;
break;
case NOUVEAU_BUS_PLATFORM:
device->platformdev = dev;
break;
}
device->handle = name;
device->cfgopt = cfg;
device->dbgopt = dbg;
device->name = sname;
nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
nv_engine(device)->sclass = nouveau_device_sclass;
list_add(&device->head, &nv_devices);
done:
mutex_unlock(&nv_devices_mutex);
return ret;
}

View File

@ -0,0 +1,144 @@
/*
* 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 <core/object.h>
#include <core/class.h>
#include <subdev/clock.h>
#include "priv.h"
static int
nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
{
struct nouveau_clock *clk = nouveau_clock(object);
struct nv_control_pstate_info *args = data;
if (size < sizeof(*args))
return -EINVAL;
if (clk) {
args->count = clk->state_nr;
args->ustate = clk->ustate;
args->pstate = clk->pstate;
} else {
args->count = 0;
args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE;
args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN;
}
return 0;
}
static int
nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
{
struct nouveau_clock *clk = nouveau_clock(object);
struct nv_control_pstate_attr *args = data;
struct nouveau_clocks *domain;
struct nouveau_pstate *pstate;
struct nouveau_cstate *cstate;
int i = 0, j = -1;
u32 lo, hi;
if ((size < sizeof(*args)) || !clk ||
(args->state >= 0 && args->state >= clk->state_nr))
return -EINVAL;
domain = clk->domains;
while (domain->name != nv_clk_src_max) {
if (domain->mname && ++j == args->index)
break;
domain++;
}
if (domain->name == nv_clk_src_max)
return -EINVAL;
if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) {
list_for_each_entry(pstate, &clk->states, head) {
if (i++ == args->state)
break;
}
lo = pstate->base.domain[domain->name];
hi = lo;
list_for_each_entry(cstate, &pstate->list, head) {
lo = min(lo, cstate->domain[domain->name]);
hi = max(hi, cstate->domain[domain->name]);
}
args->state = pstate->pstate;
} else {
lo = max(clk->read(clk, domain->name), 0);
hi = lo;
}
snprintf(args->name, sizeof(args->name), "%s", domain->mname);
snprintf(args->unit, sizeof(args->unit), "MHz");
args->min = lo / domain->mdiv;
args->max = hi / domain->mdiv;
args->index = 0;
while ((++domain)->name != nv_clk_src_max) {
if (domain->mname) {
args->index = ++j;
break;
}
}
return 0;
}
static int
nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
{
struct nouveau_clock *clk = nouveau_clock(object);
struct nv_control_pstate_user *args = data;
if (size < sizeof(*args) || !clk)
return -EINVAL;
return nouveau_clock_ustate(clk, args->state);
}
struct nouveau_oclass
nouveau_control_oclass[] = {
{ .handle = NV_CONTROL_CLASS,
.ofuncs = &nouveau_object_ofuncs,
.omthds = (struct nouveau_omthds[]) {
{ NV_CONTROL_PSTATE_INFO,
NV_CONTROL_PSTATE_INFO, nouveau_control_mthd_pstate_info },
{ NV_CONTROL_PSTATE_ATTR,
NV_CONTROL_PSTATE_ATTR, nouveau_control_mthd_pstate_attr },
{ NV_CONTROL_PSTATE_USER,
NV_CONTROL_PSTATE_USER, nouveau_control_mthd_pstate_user },
{},
},
},
{}
};

View File

@ -0,0 +1,106 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/therm.h>
#include <subdev/mxm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/ltcg.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
#include <subdev/pwr.h>
#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/disp.h>
#include <engine/copy.h>
#include <engine/bsp.h>
#include <engine/vp.h>
#include <engine/ppp.h>
#include <engine/perfmon.h>
int
gm100_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x117:
device->cname = "GM107";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
#endif
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = gm107_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gm107_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_PWR ] = &nv108_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
#endif
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm107_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = gm107_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
#if 0
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
#endif
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
#if 0
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
#endif
break;
default:
nv_fatal(device, "unknown Maxwell chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,89 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/disp.h>
int
nv04_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x04:
device->cname = "NV04";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv04_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x05:
device->cname = "NV05";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv05_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
nv_fatal(device, "unknown RIVA chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,204 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/disp.h>
int
nv10_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x10:
device->cname = "NV10";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x15:
device->cname = "NV15";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x16:
device->cname = "NV16";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x1a:
device->cname = "nForce";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x11:
device->cname = "NV11";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x17:
device->cname = "NV17";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x1f:
device->cname = "nForce2";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x18:
device->cname = "NV18";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
nv_fatal(device, "unknown Celsius chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,131 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/therm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/disp.h>
int
nv20_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x20:
device->cname = "NV20";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv20_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x25:
device->cname = "NV25";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x28:
device->cname = "NV28";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x2a:
device->cname = "NV2A";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
nv_fatal(device, "unknown Kelvin chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,153 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/mpeg.h>
#include <engine/disp.h>
int
nv30_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x30:
device->cname = "NV30";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x35:
device->cname = "NV35";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv35_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x31:
device->cname = "NV31";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x36:
device->cname = "NV36";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv36_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
case 0x34:
device->cname = "NV34";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
default:
nv_fatal(device, "unknown Rankine chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,427 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/vm.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/therm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/mpeg.h>
#include <engine/disp.h>
#include <engine/perfmon.h>
int
nv40_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x40:
device->cname = "NV40";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x41:
device->cname = "NV41";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x42:
device->cname = "NV42";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x43:
device->cname = "NV43";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x45:
device->cname = "NV45";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x47:
device->cname = "G70";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv47_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x49:
device->cname = "G71";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4b:
device->cname = "G73";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x44:
device->cname = "NV44";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x46:
device->cname = "G72";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4a:
device->cname = "NV44A";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4c:
device->cname = "C61";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x4e:
device->cname = "C51";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv4e_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x63:
device->cname = "C73";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x67:
device->cname = "C67";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
case 0x68:
device->cname = "C68";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass;
break;
default:
nv_fatal(device, "unknown Curie chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,460 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/therm.h>
#include <subdev/mxm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
#include <subdev/pwr.h>
#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/mpeg.h>
#include <engine/vp.h>
#include <engine/crypt.h>
#include <engine/bsp.h>
#include <engine/ppp.h>
#include <engine/copy.h>
#include <engine/disp.h>
#include <engine/perfmon.h>
int
nv50_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x50:
device->cname = "G80";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv50_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv50_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv50_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv50_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv50_perfmon_oclass;
break;
case 0x84:
device->cname = "G84";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x86:
device->cname = "G86";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x92:
device->cname = "G92";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x94:
device->cname = "G94";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x96:
device->cname = "G96";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0x98:
device->cname = "G98";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv98_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xa0:
device->cname = "G200";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv84_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva0_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xaa:
device->cname = "MCP77/MCP78";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv98_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xac:
device->cname = "MCP79/MCP7A";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nv98_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass;
break;
case 0xa3:
device->cname = "GT215";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
case 0xa5:
device->cname = "GT216";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
case 0xa8:
device->cname = "GT218";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nva3_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
case 0xaf:
device->cname = "MCP89";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvaf_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvaf_fb_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass;
break;
default:
nv_fatal(device, "unknown Tesla chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,348 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/therm.h>
#include <subdev/mxm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/ltcg.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
#include <subdev/pwr.h>
#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/vp.h>
#include <engine/bsp.h>
#include <engine/ppp.h>
#include <engine/copy.h>
#include <engine/disp.h>
#include <engine/perfmon.h>
int
nvc0_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0xc0:
device->cname = "GF100";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc0_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc4:
device->cname = "GF104";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc3:
device->cname = "GF106";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xce:
device->cname = "GF114";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xcf:
device->cname = "GF116";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc1:
device->cname = "GF108";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc1_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xc8:
device->cname = "GF110";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvc8_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xd9:
device->cname = "GF119";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvd9_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nvd0_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
case 0xd7:
device->cname = "GF117";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvd7_graph_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nvd0_disp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
break;
default:
nv_fatal(device, "unknown Fermi chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,234 @@
/*
* 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 <subdev/bios.h>
#include <subdev/bus.h>
#include <subdev/gpio.h>
#include <subdev/i2c.h>
#include <subdev/clock.h>
#include <subdev/therm.h>
#include <subdev/mxm.h>
#include <subdev/devinit.h>
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/ltcg.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
#include <subdev/bar.h>
#include <subdev/pwr.h>
#include <subdev/volt.h>
#include <engine/device.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include <engine/software.h>
#include <engine/graph.h>
#include <engine/disp.h>
#include <engine/copy.h>
#include <engine/bsp.h>
#include <engine/vp.h>
#include <engine/ppp.h>
#include <engine/perfmon.h>
int
nve0_identify(struct nouveau_device *device)
{
switch (device->chipset) {
case 0xe4:
device->cname = "GK104";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_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_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
case 0xe7:
device->cname = "GK107";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_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_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
case 0xe6:
device->cname = "GK106";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_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_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
break;
case 0xf0:
device->cname = "GK110";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
#if 0
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
#endif
device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
break;
case 0x108:
device->cname = "GK208";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
device->oclass[NVDEV_SUBDEV_PWR ] = &nv108_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
#if 0
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
#endif
break;
default:
nv_fatal(device, "unknown Kepler chipset\n");
return -EINVAL;
}
return 0;
}

View File

@ -0,0 +1,8 @@
#ifndef __NVKM_DEVICE_PRIV_H__
#define __NVKM_DEVICE_PRIV_H__
#include <engine/device.h>
extern struct nouveau_oclass nouveau_control_oclass[];
#endif

View File

@ -0,0 +1,52 @@
/*
* 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
*/
#include <engine/disp.h>
void
_nouveau_disp_dtor(struct nouveau_object *object)
{
struct nouveau_disp *disp = (void *)object;
nouveau_event_destroy(&disp->vblank);
nouveau_engine_destroy(&disp->base);
}
int
nouveau_disp_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, int heads,
const char *intname, const char *extname,
int length, void **pobject)
{
struct nouveau_disp *disp;
int ret;
ret = nouveau_engine_create_(parent, engine, oclass, true,
intname, extname, length, pobject);
disp = *pobject;
if (ret)
return ret;
return nouveau_event_create(heads, &disp->vblank);
}

View File

@ -0,0 +1,98 @@
/*
* 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/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
#include "nv50.h"
int
nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data)
{
const u32 stat = (data & NV50_DISP_DAC_PWR_HSYNC) |
(data & NV50_DISP_DAC_PWR_VSYNC) |
(data & NV50_DISP_DAC_PWR_DATA) |
(data & NV50_DISP_DAC_PWR_STATE);
const u32 doff = (or * 0x800);
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
nv_mask(priv, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat);
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
return 0;
}
int
nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
{
const u32 doff = (or * 0x800);
nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000);
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval);
mdelay(9);
udelay(500);
loadval = nv_mask(priv, 0x61a00c + doff, 0xffffffff, 0x00000000);
nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000);
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval);
if (!(loadval & 0x80000000))
return -ETIMEDOUT;
return (loadval & 0x38000000) >> 27;
}
int
nv50_dac_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
{
struct nv50_disp_priv *priv = (void *)object->engine;
const u8 or = (mthd & NV50_DISP_DAC_MTHD_OR);
u32 *data = args;
int ret;
if (size < sizeof(u32))
return -EINVAL;
switch (mthd & ~0x3f) {
case NV50_DISP_DAC_PWR:
ret = priv->dac.power(priv, or, data[0]);
break;
case NV50_DISP_DAC_LOAD:
ret = priv->dac.sense(priv, or, data[0]);
if (ret >= 0) {
data[0] = ret;
ret = 0;
}
break;
default:
BUG_ON(1);
}
return ret;
}

View File

@ -0,0 +1,372 @@
/*
* 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
*/
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/init.h>
#include <subdev/i2c.h>
#include <engine/disp.h>
#include "dport.h"
#define DBG(fmt, args...) nv_debug(dp->disp, "DP:%04x:%04x: " fmt, \
dp->outp->hasht, dp->outp->hashm, ##args)
#define ERR(fmt, args...) nv_error(dp->disp, "DP:%04x:%04x: " fmt, \
dp->outp->hasht, dp->outp->hashm, ##args)
/******************************************************************************
* link training
*****************************************************************************/
struct dp_state {
const struct nouveau_dp_func *func;
struct nouveau_disp *disp;
struct dcb_output *outp;
struct nvbios_dpout info;
u8 version;
struct nouveau_i2c_port *aux;
int head;
u8 dpcd[4];
int link_nr;
u32 link_bw;
u8 stat[6];
u8 conf[4];
};
static int
dp_set_link_config(struct dp_state *dp)
{
struct nouveau_disp *disp = dp->disp;
struct nouveau_bios *bios = nouveau_bios(disp);
struct nvbios_init init = {
.subdev = nv_subdev(dp->disp),
.bios = bios,
.offset = 0x0000,
.outp = dp->outp,
.crtc = dp->head,
.execute = 1,
};
u32 lnkcmp;
u8 sink[2];
int ret;
DBG("%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
/* set desired link configuration on the source */
if ((lnkcmp = dp->info.lnkcmp)) {
if (dp->version < 0x30) {
while ((dp->link_bw / 10) < nv_ro16(bios, lnkcmp))
lnkcmp += 4;
init.offset = nv_ro16(bios, lnkcmp + 2);
} else {
while ((dp->link_bw / 27000) < nv_ro08(bios, lnkcmp))
lnkcmp += 3;
init.offset = nv_ro16(bios, lnkcmp + 1);
}
nvbios_exec(&init);
}
ret = dp->func->lnk_ctl(dp->disp, dp->outp, dp->head,
dp->link_nr, dp->link_bw / 27000,
dp->dpcd[DPCD_RC02] &
DPCD_RC02_ENHANCED_FRAME_CAP);
if (ret) {
ERR("lnk_ctl failed with %d\n", ret);
return ret;
}
/* set desired link configuration on the sink */
sink[0] = dp->link_bw / 27000;
sink[1] = dp->link_nr;
if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN;
return nv_wraux(dp->aux, DPCD_LC00, sink, 2);
}
static void
dp_set_training_pattern(struct dp_state *dp, u8 pattern)
{
u8 sink_tp;
DBG("training pattern %d\n", pattern);
dp->func->pattern(dp->disp, dp->outp, dp->head, pattern);
nv_rdaux(dp->aux, DPCD_LC02, &sink_tp, 1);
sink_tp &= ~DPCD_LC02_TRAINING_PATTERN_SET;
sink_tp |= pattern;
nv_wraux(dp->aux, DPCD_LC02, &sink_tp, 1);
}
static int
dp_link_train_commit(struct dp_state *dp)
{
int i;
for (i = 0; i < dp->link_nr; i++) {
u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf;
u8 lpre = (lane & 0x0c) >> 2;
u8 lvsw = (lane & 0x03) >> 0;
dp->conf[i] = (lpre << 3) | lvsw;
if (lvsw == 3)
dp->conf[i] |= DPCD_LC03_MAX_SWING_REACHED;
if (lpre == 3)
dp->conf[i] |= DPCD_LC03_MAX_PRE_EMPHASIS_REACHED;
DBG("config lane %d %02x\n", i, dp->conf[i]);
dp->func->drv_ctl(dp->disp, dp->outp, dp->head, i, lvsw, lpre);
}
return nv_wraux(dp->aux, DPCD_LC03(0), dp->conf, 4);
}
static int
dp_link_train_update(struct dp_state *dp, u32 delay)
{
int ret;
udelay(delay);
ret = nv_rdaux(dp->aux, DPCD_LS02, dp->stat, 6);
if (ret)
return ret;
DBG("status %6ph\n", dp->stat);
return 0;
}
static int
dp_link_train_cr(struct dp_state *dp)
{
bool cr_done = false, abort = false;
int voltage = dp->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET;
int tries = 0, i;
dp_set_training_pattern(dp, 1);
do {
if (dp_link_train_commit(dp) ||
dp_link_train_update(dp, 100))
break;
cr_done = true;
for (i = 0; i < dp->link_nr; i++) {
u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf;
if (!(lane & DPCD_LS02_LANE0_CR_DONE)) {
cr_done = false;
if (dp->conf[i] & DPCD_LC03_MAX_SWING_REACHED)
abort = true;
break;
}
}
if ((dp->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET) != voltage) {
voltage = dp->conf[0] & DPCD_LC03_VOLTAGE_SWING_SET;
tries = 0;
}
} while (!cr_done && !abort && ++tries < 5);
return cr_done ? 0 : -1;
}
static int
dp_link_train_eq(struct dp_state *dp)
{
bool eq_done = false, cr_done = true;
int tries = 0, i;
dp_set_training_pattern(dp, 2);
do {
if (dp_link_train_update(dp, 400))
break;
eq_done = !!(dp->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE);
for (i = 0; i < dp->link_nr && eq_done; i++) {
u8 lane = (dp->stat[i >> 1] >> ((i & 1) * 4)) & 0xf;
if (!(lane & DPCD_LS02_LANE0_CR_DONE))
cr_done = false;
if (!(lane & DPCD_LS02_LANE0_CHANNEL_EQ_DONE) ||
!(lane & DPCD_LS02_LANE0_SYMBOL_LOCKED))
eq_done = false;
}
if (dp_link_train_commit(dp))
break;
} while (!eq_done && cr_done && ++tries <= 5);
return eq_done ? 0 : -1;
}
static void
dp_link_train_init(struct dp_state *dp, bool spread)
{
struct nvbios_init init = {
.subdev = nv_subdev(dp->disp),
.bios = nouveau_bios(dp->disp),
.outp = dp->outp,
.crtc = dp->head,
.execute = 1,
};
/* set desired spread */
if (spread)
init.offset = dp->info.script[2];
else
init.offset = dp->info.script[3];
nvbios_exec(&init);
/* pre-train script */
init.offset = dp->info.script[0];
nvbios_exec(&init);
}
static void
dp_link_train_fini(struct dp_state *dp)
{
struct nvbios_init init = {
.subdev = nv_subdev(dp->disp),
.bios = nouveau_bios(dp->disp),
.outp = dp->outp,
.crtc = dp->head,
.execute = 1,
};
/* post-train script */
init.offset = dp->info.script[1],
nvbios_exec(&init);
}
int
nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
struct dcb_output *outp, int head, u32 datarate)
{
struct nouveau_bios *bios = nouveau_bios(disp);
struct nouveau_i2c *i2c = nouveau_i2c(disp);
struct dp_state _dp = {
.disp = disp,
.func = func,
.outp = outp,
.head = head,
}, *dp = &_dp;
const u32 bw_list[] = { 540000, 270000, 162000, 0 };
const u32 *link_bw = bw_list;
u8 hdr, cnt, len;
u32 data;
int ret;
/* find the bios displayport data relevant to this output */
data = nvbios_dpout_match(bios, outp->hasht, outp->hashm, &dp->version,
&hdr, &cnt, &len, &dp->info);
if (!data) {
ERR("bios data not found\n");
return -EINVAL;
}
/* acquire the aux channel and fetch some info about the display */
if (outp->location)
dp->aux = i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(outp->extdev));
else
dp->aux = i2c->find(i2c, NV_I2C_TYPE_DCBI2C(outp->i2c_index));
if (!dp->aux) {
ERR("no aux channel?!\n");
return -ENODEV;
}
ret = nv_rdaux(dp->aux, 0x00000, dp->dpcd, sizeof(dp->dpcd));
if (ret) {
/* it's possible the display has been unplugged before we
* get here. we still need to execute the full set of
* vbios scripts, and program the OR at a high enough
* frequency to satisfy the target mode. failure to do
* so results at best in an UPDATE hanging, and at worst
* with PDISP running away to join the circus.
*/
dp->dpcd[1] = link_bw[0] / 27000;
dp->dpcd[2] = 4;
dp->dpcd[3] = 0x00;
ERR("failed to read DPCD\n");
}
/* bring capabilities within encoder limits */
if ((dp->dpcd[2] & 0x1f) > dp->outp->dpconf.link_nr) {
dp->dpcd[2] &= ~0x1f;
dp->dpcd[2] |= dp->outp->dpconf.link_nr;
}
if (dp->dpcd[1] > dp->outp->dpconf.link_bw)
dp->dpcd[1] = dp->outp->dpconf.link_bw;
/* adjust required bandwidth for 8B/10B coding overhead */
datarate = (datarate / 8) * 10;
/* enable down-spreading and execute pre-train script from vbios */
dp_link_train_init(dp, dp->dpcd[3] & 0x01);
/* start off at highest link rate supported by encoder and display */
while (*link_bw > (dp->dpcd[1] * 27000))
link_bw++;
while ((ret = -EIO) && link_bw[0]) {
/* find minimum required lane count at this link rate */
dp->link_nr = dp->dpcd[2] & DPCD_RC02_MAX_LANE_COUNT;
while ((dp->link_nr >> 1) * link_bw[0] > datarate)
dp->link_nr >>= 1;
/* drop link rate to minimum with this lane count */
while ((link_bw[1] * dp->link_nr) > datarate)
link_bw++;
dp->link_bw = link_bw[0];
/* program selected link configuration */
ret = dp_set_link_config(dp);
if (ret == 0) {
/* attempt to train the link at this configuration */
memset(dp->stat, 0x00, sizeof(dp->stat));
if (!dp_link_train_cr(dp) &&
!dp_link_train_eq(dp))
break;
} else
if (ret) {
/* dp_set_link_config() handled training, or
* we failed to communicate with the sink.
*/
break;
}
/* retry at lower rate */
link_bw++;
}
/* finish link training */
dp_set_training_pattern(dp, 0);
if (ret < 0)
ERR("link training failed\n");
/* execute post-train script from vbios */
dp_link_train_fini(dp);
return (ret < 0) ? false : true;
}

View File

@ -0,0 +1,78 @@
#ifndef __NVKM_DISP_DPORT_H__
#define __NVKM_DISP_DPORT_H__
/* DPCD Receiver Capabilities */
#define DPCD_RC00 0x00000
#define DPCD_RC00_DPCD_REV 0xff
#define DPCD_RC01 0x00001
#define DPCD_RC01_MAX_LINK_RATE 0xff
#define DPCD_RC02 0x00002
#define DPCD_RC02_ENHANCED_FRAME_CAP 0x80
#define DPCD_RC02_MAX_LANE_COUNT 0x1f
#define DPCD_RC03 0x00003
#define DPCD_RC03_MAX_DOWNSPREAD 0x01
/* DPCD Link Configuration */
#define DPCD_LC00 0x00100
#define DPCD_LC00_LINK_BW_SET 0xff
#define DPCD_LC01 0x00101
#define DPCD_LC01_ENHANCED_FRAME_EN 0x80
#define DPCD_LC01_LANE_COUNT_SET 0x1f
#define DPCD_LC02 0x00102
#define DPCD_LC02_TRAINING_PATTERN_SET 0x03
#define DPCD_LC03(l) ((l) + 0x00103)
#define DPCD_LC03_MAX_PRE_EMPHASIS_REACHED 0x20
#define DPCD_LC03_PRE_EMPHASIS_SET 0x18
#define DPCD_LC03_MAX_SWING_REACHED 0x04
#define DPCD_LC03_VOLTAGE_SWING_SET 0x03
/* DPCD Link/Sink Status */
#define DPCD_LS02 0x00202
#define DPCD_LS02_LANE1_SYMBOL_LOCKED 0x40
#define DPCD_LS02_LANE1_CHANNEL_EQ_DONE 0x20
#define DPCD_LS02_LANE1_CR_DONE 0x10
#define DPCD_LS02_LANE0_SYMBOL_LOCKED 0x04
#define DPCD_LS02_LANE0_CHANNEL_EQ_DONE 0x02
#define DPCD_LS02_LANE0_CR_DONE 0x01
#define DPCD_LS03 0x00203
#define DPCD_LS03_LANE3_SYMBOL_LOCKED 0x40
#define DPCD_LS03_LANE3_CHANNEL_EQ_DONE 0x20
#define DPCD_LS03_LANE3_CR_DONE 0x10
#define DPCD_LS03_LANE2_SYMBOL_LOCKED 0x04
#define DPCD_LS03_LANE2_CHANNEL_EQ_DONE 0x02
#define DPCD_LS03_LANE2_CR_DONE 0x01
#define DPCD_LS04 0x00204
#define DPCD_LS04_LINK_STATUS_UPDATED 0x80
#define DPCD_LS04_DOWNSTREAM_PORT_STATUS_CHANGED 0x40
#define DPCD_LS04_INTERLANE_ALIGN_DONE 0x01
#define DPCD_LS06 0x00206
#define DPCD_LS06_LANE1_PRE_EMPHASIS 0xc0
#define DPCD_LS06_LANE1_VOLTAGE_SWING 0x30
#define DPCD_LS06_LANE0_PRE_EMPHASIS 0x0c
#define DPCD_LS06_LANE0_VOLTAGE_SWING 0x03
#define DPCD_LS07 0x00207
#define DPCD_LS07_LANE3_PRE_EMPHASIS 0xc0
#define DPCD_LS07_LANE3_VOLTAGE_SWING 0x30
#define DPCD_LS07_LANE2_PRE_EMPHASIS 0x0c
#define DPCD_LS07_LANE2_VOLTAGE_SWING 0x03
struct nouveau_disp;
struct dcb_output;
struct nouveau_dp_func {
int (*pattern)(struct nouveau_disp *, struct dcb_output *,
int head, int pattern);
int (*lnk_ctl)(struct nouveau_disp *, struct dcb_output *, int head,
int link_nr, int link_bw, bool enh_frame);
int (*drv_ctl)(struct nouveau_disp *, struct dcb_output *, int head,
int lane, int swing, int preem);
};
extern const struct nouveau_dp_func nv94_sor_dp_func;
extern const struct nouveau_dp_func nvd0_sor_dp_func;
extern const struct nouveau_dp_func nv50_pior_dp_func;
int nouveau_dp_train(struct nouveau_disp *, const struct nouveau_dp_func *,
struct dcb_output *, int, u32);
#endif

View File

@ -0,0 +1,101 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
gm107_disp_sclass[] = {
{ GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
{ GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
{ GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
{ GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
{ GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
{}
};
static struct nouveau_oclass
gm107_disp_base_oclass[] = {
{ GM107_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = gm107_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr;
INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
priv->sclass = gm107_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hda_eld = nvd0_hda_eld;
priv->sor.hdmi = nvd0_hdmi_ctrl;
priv->sor.dp = &nvd0_sor_dp_func;
return 0;
}
struct nouveau_oclass *
gm107_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x07),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = gm107_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nve0_disp_mast_mthd_chan,
.mthd.base = &nvd0_disp_sync_mthd_chan,
.mthd.ovly = &nve0_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
}.base.base;

View File

@ -0,0 +1,50 @@
/*
* 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/os.h>
#include <core/class.h>
#include "nv50.h"
int
nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size)
{
const u32 soff = (or * 0x800);
int i;
if (data && data[0]) {
for (i = 0; i < size; i++)
nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]);
for (; i < 0x60; i++)
nv_wr32(priv, 0x61c440 + soff, (i << 8));
nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003);
} else
if (data) {
nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000001);
} else {
nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000000);
}
return 0;
}

View File

@ -0,0 +1,55 @@
/*
* 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/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/init.h>
#include "nv50.h"
int
nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size)
{
const u32 soff = (or * 0x030);
int i;
if (data && data[0]) {
for (i = 0; i < size; i++)
nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]);
for (; i < 0x60; i++)
nv_wr32(priv, 0x10ec00 + soff, (i << 8));
nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003);
} else
if (data) {
nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001);
} else {
nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000);
}
return 0;
}

View File

@ -0,0 +1,70 @@
/*
* 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/os.h>
#include <core/class.h>
#include "nv50.h"
int
nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
{
const u32 hoff = (head * 0x800);
if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) {
nv_mask(priv, 0x6165a4 + hoff, 0x40000000, 0x00000000);
nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000000);
nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000000);
return 0;
}
/* AVI InfoFrame */
nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000000);
nv_wr32(priv, 0x616528 + hoff, 0x000d0282);
nv_wr32(priv, 0x61652c + hoff, 0x0000006f);
nv_wr32(priv, 0x616530 + hoff, 0x00000000);
nv_wr32(priv, 0x616534 + hoff, 0x00000000);
nv_wr32(priv, 0x616538 + hoff, 0x00000000);
nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000001);
/* Audio InfoFrame */
nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000000);
nv_wr32(priv, 0x616508 + hoff, 0x000a0184);
nv_wr32(priv, 0x61650c + hoff, 0x00000071);
nv_wr32(priv, 0x616510 + hoff, 0x00000000);
nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000001);
nv_mask(priv, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
nv_mask(priv, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
nv_mask(priv, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
/* ??? */
nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
/* HDMI_CTRL */
nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, data | 0x1f000000 /* ??? */);
return 0;
}

View File

@ -0,0 +1,70 @@
/*
* 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/os.h>
#include <core/class.h>
#include "nv50.h"
int
nva3_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
{
const u32 soff = (or * 0x800);
if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) {
nv_mask(priv, 0x61c5a4 + soff, 0x40000000, 0x00000000);
nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000000);
nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000000);
return 0;
}
/* AVI InfoFrame */
nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000000);
nv_wr32(priv, 0x61c528 + soff, 0x000d0282);
nv_wr32(priv, 0x61c52c + soff, 0x0000006f);
nv_wr32(priv, 0x61c530 + soff, 0x00000000);
nv_wr32(priv, 0x61c534 + soff, 0x00000000);
nv_wr32(priv, 0x61c538 + soff, 0x00000000);
nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000001);
/* Audio InfoFrame */
nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000000);
nv_wr32(priv, 0x61c508 + soff, 0x000a0184);
nv_wr32(priv, 0x61c50c + soff, 0x00000071);
nv_wr32(priv, 0x61c510 + soff, 0x00000000);
nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000001);
nv_mask(priv, 0x61c5d0 + soff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */
nv_mask(priv, 0x61c568 + soff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */
nv_mask(priv, 0x61c578 + soff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */
/* ??? */
nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */
nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */
nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
/* HDMI_CTRL */
nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, data | 0x1f000000 /* ??? */);
return 0;
}

View File

@ -0,0 +1,62 @@
/*
* 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/os.h>
#include <core/class.h>
#include "nv50.h"
int
nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
{
const u32 hoff = (head * 0x800);
if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) {
nv_mask(priv, 0x616798 + hoff, 0x40000000, 0x00000000);
nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000);
nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000);
return 0;
}
/* AVI InfoFrame */
nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000);
nv_wr32(priv, 0x61671c + hoff, 0x000d0282);
nv_wr32(priv, 0x616720 + hoff, 0x0000006f);
nv_wr32(priv, 0x616724 + hoff, 0x00000000);
nv_wr32(priv, 0x616728 + hoff, 0x00000000);
nv_wr32(priv, 0x61672c + hoff, 0x00000000);
nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000001);
/* ??? InfoFrame? */
nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000);
nv_wr32(priv, 0x6167ac + hoff, 0x00000010);
nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000001);
/* HDMI_CTRL */
nv_mask(priv, 0x616798 + hoff, 0x401f007f, data);
/* NFI, audio doesn't work without it though.. */
nv_mask(priv, 0x616548 + hoff, 0x00000070, 0x00000000);
return 0;
}

View File

@ -0,0 +1,150 @@
/*
* 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 "priv.h"
#include <core/event.h>
#include <core/class.h>
struct nv04_disp_priv {
struct nouveau_disp base;
};
static int
nv04_disp_scanoutpos(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
{
struct nv04_disp_priv *priv = (void *)object->engine;
struct nv04_display_scanoutpos *args = data;
const int head = (mthd & NV04_DISP_MTHD_HEAD);
u32 line;
if (size < sizeof(*args))
return -EINVAL;
args->vblanks = nv_rd32(priv, 0x680800 + (head * 0x2000)) & 0xffff;
args->vtotal = nv_rd32(priv, 0x680804 + (head * 0x2000)) & 0xffff;
args->vblanke = args->vtotal - 1;
args->hblanks = nv_rd32(priv, 0x680820 + (head * 0x2000)) & 0xffff;
args->htotal = nv_rd32(priv, 0x680824 + (head * 0x2000)) & 0xffff;
args->hblanke = args->htotal - 1;
args->time[0] = ktime_to_ns(ktime_get());
line = nv_rd32(priv, 0x600868 + (head * 0x2000));
args->time[1] = ktime_to_ns(ktime_get());
args->hline = (line & 0xffff0000) >> 16;
args->vline = (line & 0x0000ffff);
return 0;
}
#define HEAD_MTHD(n) (n), (n) + 0x01
static struct nouveau_omthds
nv04_disp_omthds[] = {
{ HEAD_MTHD(NV04_DISP_SCANOUTPOS), nv04_disp_scanoutpos },
{}
};
static struct nouveau_oclass
nv04_disp_sclass[] = {
{ NV04_DISP_CLASS, &nouveau_object_ofuncs, nv04_disp_omthds },
{},
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static void
nv04_disp_vblank_enable(struct nouveau_event *event, int head)
{
nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001);
}
static void
nv04_disp_vblank_disable(struct nouveau_event *event, int head)
{
nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000);
}
static void
nv04_disp_intr(struct nouveau_subdev *subdev)
{
struct nv04_disp_priv *priv = (void *)subdev;
u32 crtc0 = nv_rd32(priv, 0x600100);
u32 crtc1 = nv_rd32(priv, 0x602100);
u32 pvideo;
if (crtc0 & 0x00000001) {
nouveau_event_trigger(priv->base.vblank, 0);
nv_wr32(priv, 0x600100, 0x00000001);
}
if (crtc1 & 0x00000001) {
nouveau_event_trigger(priv->base.vblank, 1);
nv_wr32(priv, 0x602100, 0x00000001);
}
if (nv_device(priv)->chipset >= 0x10 &&
nv_device(priv)->chipset <= 0x40) {
pvideo = nv_rd32(priv, 0x8100);
if (pvideo & ~0x11)
nv_info(priv, "PVIDEO intr: %08x\n", pvideo);
nv_wr32(priv, 0x8100, pvideo);
}
}
static int
nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_disp_priv *priv;
int ret;
ret = nouveau_disp_create(parent, engine, oclass, 2, "DISPLAY",
"display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nv04_disp_sclass;
nv_subdev(priv)->intr = nv04_disp_intr;
priv->base.vblank->priv = priv;
priv->base.vblank->enable = nv04_disp_vblank_enable;
priv->base.vblank->disable = nv04_disp_vblank_disable;
return 0;
}
struct nouveau_oclass *
nv04_disp_oclass = &(struct nouveau_disp_impl) {
.base.handle = NV_ENGINE(DISP, 0x04),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
}.base;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
#ifndef __NV50_DISP_H__
#define __NV50_DISP_H__
#include <core/parent.h>
#include <core/namedb.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <core/event.h>
#include <engine/dmaobj.h>
#include "dport.h"
#include "priv.h"
struct nv50_disp_impl {
struct nouveau_disp_impl base;
struct {
const struct nv50_disp_mthd_chan *core;
const struct nv50_disp_mthd_chan *base;
const struct nv50_disp_mthd_chan *ovly;
int prev;
} mthd;
};
struct nv50_disp_priv {
struct nouveau_disp base;
struct nouveau_oclass *sclass;
struct work_struct supervisor;
u32 super;
struct {
int nr;
} head;
struct {
int nr;
int (*power)(struct nv50_disp_priv *, int dac, u32 data);
int (*sense)(struct nv50_disp_priv *, int dac, u32 load);
} dac;
struct {
int nr;
int (*power)(struct nv50_disp_priv *, int sor, u32 data);
int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32);
int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32);
u32 lvdsconf;
const struct nouveau_dp_func *dp;
} sor;
struct {
int nr;
int (*power)(struct nv50_disp_priv *, int ext, u32 data);
u8 type[3];
const struct nouveau_dp_func *dp;
} pior;
};
#define HEAD_MTHD(n) (n), (n) + 0x03
int nv50_disp_base_scanoutpos(struct nouveau_object *, u32, void *, u32);
#define DAC_MTHD(n) (n), (n) + 0x03
int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32);
int nv50_dac_power(struct nv50_disp_priv *, int, u32);
int nv50_dac_sense(struct nv50_disp_priv *, int, u32);
#define SOR_MTHD(n) (n), (n) + 0x3f
int nva3_hda_eld(struct nv50_disp_priv *, int, u8 *, u32);
int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32);
int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32);
int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32);
int nvd0_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32);
int nv50_sor_mthd(struct nouveau_object *, u32, void *, u32);
int nv50_sor_power(struct nv50_disp_priv *, int, u32);
int nv94_sor_dp_train_init(struct nv50_disp_priv *, int, int, int, u16, u16,
u32, struct dcb_output *);
int nv94_sor_dp_train_fini(struct nv50_disp_priv *, int, int, int, u16, u16,
u32, struct dcb_output *);
int nv94_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32,
struct dcb_output *);
int nv94_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
struct dcb_output *);
int nv94_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
struct dcb_output *);
int nvd0_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32,
struct dcb_output *);
int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
struct dcb_output *);
int nvd0_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32,
struct dcb_output *);
#define PIOR_MTHD(n) (n), (n) + 0x03
int nv50_pior_mthd(struct nouveau_object *, u32, void *, u32);
int nv50_pior_power(struct nv50_disp_priv *, int, u32);
struct nv50_disp_base {
struct nouveau_parent base;
struct nouveau_ramht *ramht;
u32 chan;
};
struct nv50_disp_chan {
struct nouveau_namedb base;
int chid;
};
int nv50_disp_chan_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, int, void **);
void nv50_disp_chan_destroy(struct nv50_disp_chan *);
u32 nv50_disp_chan_rd32(struct nouveau_object *, u64);
void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);
#define nv50_disp_chan_init(a) \
nouveau_namedb_init(&(a)->base)
#define nv50_disp_chan_fini(a,b) \
nouveau_namedb_fini(&(a)->base, (b))
int nv50_disp_dmac_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, u32, int, int, void **);
void nv50_disp_dmac_dtor(struct nouveau_object *);
struct nv50_disp_dmac {
struct nv50_disp_chan base;
struct nouveau_dmaobj *pushdma;
u32 push;
};
struct nv50_disp_pioc {
struct nv50_disp_chan base;
};
struct nv50_disp_mthd_list {
u32 mthd;
u32 addr;
struct {
u32 mthd;
u32 addr;
const char *name;
} data[];
};
struct nv50_disp_mthd_chan {
const char *name;
u32 addr;
struct {
const char *name;
int nr;
const struct nv50_disp_mthd_list *mthd;
} data[];
};
extern struct nouveau_ofuncs nv50_disp_mast_ofuncs;
extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_base;
extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_sor;
extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_pior;
extern struct nouveau_ofuncs nv50_disp_sync_ofuncs;
extern const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image;
extern struct nouveau_ofuncs nv50_disp_ovly_ofuncs;
extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base;
extern struct nouveau_ofuncs nv50_disp_oimm_ofuncs;
extern struct nouveau_ofuncs nv50_disp_curs_ofuncs;
extern struct nouveau_ofuncs nv50_disp_base_ofuncs;
extern struct nouveau_oclass nv50_disp_cclass;
void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head,
const struct nv50_disp_mthd_chan *);
void nv50_disp_intr_supervisor(struct work_struct *);
void nv50_disp_intr(struct nouveau_subdev *);
extern const struct nv50_disp_mthd_chan nv84_disp_mast_mthd_chan;
extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_dac;
extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_head;
extern const struct nv50_disp_mthd_chan nv84_disp_sync_mthd_chan;
extern const struct nv50_disp_mthd_chan nv84_disp_ovly_mthd_chan;
extern struct nouveau_omthds nv84_disp_base_omthds[];
extern const struct nv50_disp_mthd_chan nv94_disp_mast_mthd_chan;
extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_base;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_dac;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_sor;
extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_pior;
extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs;
extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs;
extern const struct nv50_disp_mthd_chan nvd0_disp_sync_mthd_chan;
extern struct nouveau_ofuncs nvd0_disp_oimm_ofuncs;
extern struct nouveau_ofuncs nvd0_disp_curs_ofuncs;
extern struct nouveau_omthds nvd0_disp_base_omthds[];
extern struct nouveau_ofuncs nvd0_disp_base_ofuncs;
extern struct nouveau_oclass nvd0_disp_cclass;
void nvd0_disp_intr_supervisor(struct work_struct *);
void nvd0_disp_intr(struct nouveau_subdev *);
extern const struct nv50_disp_mthd_chan nve0_disp_mast_mthd_chan;
extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan;
#endif

View File

@ -0,0 +1,284 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* EVO master channel object
******************************************************************************/
const struct nv50_disp_mthd_list
nv84_disp_mast_mthd_dac = {
.mthd = 0x0080,
.addr = 0x000008,
.data = {
{ 0x0400, 0x610b58 },
{ 0x0404, 0x610bdc },
{ 0x0420, 0x610bc4 },
{}
}
};
const struct nv50_disp_mthd_list
nv84_disp_mast_mthd_head = {
.mthd = 0x0400,
.addr = 0x000540,
.data = {
{ 0x0800, 0x610ad8 },
{ 0x0804, 0x610ad0 },
{ 0x0808, 0x610a48 },
{ 0x080c, 0x610a78 },
{ 0x0810, 0x610ac0 },
{ 0x0814, 0x610af8 },
{ 0x0818, 0x610b00 },
{ 0x081c, 0x610ae8 },
{ 0x0820, 0x610af0 },
{ 0x0824, 0x610b08 },
{ 0x0828, 0x610b10 },
{ 0x082c, 0x610a68 },
{ 0x0830, 0x610a60 },
{ 0x0834, 0x000000 },
{ 0x0838, 0x610a40 },
{ 0x0840, 0x610a24 },
{ 0x0844, 0x610a2c },
{ 0x0848, 0x610aa8 },
{ 0x084c, 0x610ab0 },
{ 0x085c, 0x610c5c },
{ 0x0860, 0x610a84 },
{ 0x0864, 0x610a90 },
{ 0x0868, 0x610b18 },
{ 0x086c, 0x610b20 },
{ 0x0870, 0x610ac8 },
{ 0x0874, 0x610a38 },
{ 0x0878, 0x610c50 },
{ 0x0880, 0x610a58 },
{ 0x0884, 0x610a9c },
{ 0x089c, 0x610c68 },
{ 0x08a0, 0x610a70 },
{ 0x08a4, 0x610a50 },
{ 0x08a8, 0x610ae0 },
{ 0x08c0, 0x610b28 },
{ 0x08c4, 0x610b30 },
{ 0x08c8, 0x610b40 },
{ 0x08d4, 0x610b38 },
{ 0x08d8, 0x610b48 },
{ 0x08dc, 0x610b50 },
{ 0x0900, 0x610a18 },
{ 0x0904, 0x610ab8 },
{ 0x0910, 0x610c70 },
{ 0x0914, 0x610c78 },
{}
}
};
const struct nv50_disp_mthd_chan
nv84_disp_mast_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
{ "Global", 1, &nv50_disp_mast_mthd_base },
{ "DAC", 3, &nv84_disp_mast_mthd_dac },
{ "SOR", 2, &nv50_disp_mast_mthd_sor },
{ "PIOR", 3, &nv50_disp_mast_mthd_pior },
{ "HEAD", 2, &nv84_disp_mast_mthd_head },
{}
}
};
/*******************************************************************************
* EVO sync channel objects
******************************************************************************/
static const struct nv50_disp_mthd_list
nv84_disp_sync_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
{ 0x0080, 0x000000 },
{ 0x0084, 0x0008c4 },
{ 0x0088, 0x0008d0 },
{ 0x008c, 0x0008dc },
{ 0x0090, 0x0008e4 },
{ 0x0094, 0x610884 },
{ 0x00a0, 0x6108a0 },
{ 0x00a4, 0x610878 },
{ 0x00c0, 0x61086c },
{ 0x00c4, 0x610800 },
{ 0x00c8, 0x61080c },
{ 0x00cc, 0x610818 },
{ 0x00e0, 0x610858 },
{ 0x00e4, 0x610860 },
{ 0x00e8, 0x6108ac },
{ 0x00ec, 0x6108b4 },
{ 0x00fc, 0x610824 },
{ 0x0100, 0x610894 },
{ 0x0104, 0x61082c },
{ 0x0110, 0x6108bc },
{ 0x0114, 0x61088c },
{}
}
};
const struct nv50_disp_mthd_chan
nv84_disp_sync_mthd_chan = {
.name = "Base",
.addr = 0x000540,
.data = {
{ "Global", 1, &nv84_disp_sync_mthd_base },
{ "Image", 2, &nv50_disp_sync_mthd_image },
{}
}
};
/*******************************************************************************
* EVO overlay channel objects
******************************************************************************/
static const struct nv50_disp_mthd_list
nv84_disp_ovly_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
{ 0x0080, 0x000000 },
{ 0x0084, 0x6109a0 },
{ 0x0088, 0x6109c0 },
{ 0x008c, 0x6109c8 },
{ 0x0090, 0x6109b4 },
{ 0x0094, 0x610970 },
{ 0x00a0, 0x610998 },
{ 0x00a4, 0x610964 },
{ 0x00c0, 0x610958 },
{ 0x00e0, 0x6109a8 },
{ 0x00e4, 0x6109d0 },
{ 0x00e8, 0x6109d8 },
{ 0x0100, 0x61094c },
{ 0x0104, 0x610984 },
{ 0x0108, 0x61098c },
{ 0x0800, 0x6109f8 },
{ 0x0808, 0x610a08 },
{ 0x080c, 0x610a10 },
{ 0x0810, 0x610a00 },
{}
}
};
const struct nv50_disp_mthd_chan
nv84_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x000540,
.data = {
{ "Global", 1, &nv84_disp_ovly_mthd_base },
{}
}
};
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
nv84_disp_sclass[] = {
{ NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
{ NV84_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
{ NV84_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
{ NV84_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
{ NV84_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
{}
};
struct nouveau_omthds
nv84_disp_base_omthds[] = {
{ HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos },
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd },
{},
};
static struct nouveau_oclass
nv84_disp_base_oclass[] = {
{ NV84_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
"display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nv84_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
priv->sclass = nv84_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 2;
priv->pior.nr = 3;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hdmi = nv84_hdmi_ctrl;
priv->pior.power = nv50_pior_power;
priv->pior.dp = &nv50_pior_dp_func;
return 0;
}
struct nouveau_oclass *
nv84_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x82),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nv84_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nv84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
}.base.base;

View File

@ -0,0 +1,144 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* EVO master channel object
******************************************************************************/
const struct nv50_disp_mthd_list
nv94_disp_mast_mthd_sor = {
.mthd = 0x0040,
.addr = 0x000008,
.data = {
{ 0x0600, 0x610794 },
{}
}
};
const struct nv50_disp_mthd_chan
nv94_disp_mast_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
{ "Global", 1, &nv50_disp_mast_mthd_base },
{ "DAC", 3, &nv84_disp_mast_mthd_dac },
{ "SOR", 4, &nv94_disp_mast_mthd_sor },
{ "PIOR", 3, &nv50_disp_mast_mthd_pior },
{ "HEAD", 2, &nv84_disp_mast_mthd_head },
{}
}
};
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
nv94_disp_sclass[] = {
{ NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
{ NV94_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
{ NV94_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
{ NV94_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
{ NV94_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
{}
};
static struct nouveau_omthds
nv94_disp_base_omthds[] = {
{ HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos },
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd },
{},
};
static struct nouveau_oclass
nv94_disp_base_oclass[] = {
{ NV94_DISP_CLASS, &nv50_disp_base_ofuncs, nv94_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
"display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nv94_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
priv->sclass = nv94_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->pior.nr = 3;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hdmi = nv84_hdmi_ctrl;
priv->sor.dp = &nv94_sor_dp_func;
priv->pior.power = nv50_pior_power;
priv->pior.dp = &nv50_pior_dp_func;
return 0;
}
struct nouveau_oclass *
nv94_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x88),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv94_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nv94_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nv84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
}.base.base;

View File

@ -0,0 +1,146 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* EVO overlay channel objects
******************************************************************************/
static const struct nv50_disp_mthd_list
nva0_disp_ovly_mthd_base = {
.mthd = 0x0000,
.addr = 0x000000,
.data = {
{ 0x0080, 0x000000 },
{ 0x0084, 0x6109a0 },
{ 0x0088, 0x6109c0 },
{ 0x008c, 0x6109c8 },
{ 0x0090, 0x6109b4 },
{ 0x0094, 0x610970 },
{ 0x00a0, 0x610998 },
{ 0x00a4, 0x610964 },
{ 0x00b0, 0x610c98 },
{ 0x00b4, 0x610ca4 },
{ 0x00b8, 0x610cac },
{ 0x00c0, 0x610958 },
{ 0x00e0, 0x6109a8 },
{ 0x00e4, 0x6109d0 },
{ 0x00e8, 0x6109d8 },
{ 0x0100, 0x61094c },
{ 0x0104, 0x610984 },
{ 0x0108, 0x61098c },
{ 0x0800, 0x6109f8 },
{ 0x0808, 0x610a08 },
{ 0x080c, 0x610a10 },
{ 0x0810, 0x610a00 },
{}
}
};
static const struct nv50_disp_mthd_chan
nva0_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x000540,
.data = {
{ "Global", 1, &nva0_disp_ovly_mthd_base },
{}
}
};
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
nva0_disp_sclass[] = {
{ NVA0_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
{ NVA0_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
{ NVA0_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
{ NVA0_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
{ NVA0_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
{}
};
static struct nouveau_oclass
nva0_disp_base_oclass[] = {
{ NVA0_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
"display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nva0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
priv->sclass = nva0_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 2;
priv->pior.nr = 3;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hdmi = nv84_hdmi_ctrl;
priv->pior.power = nv50_pior_power;
priv->pior.dp = &nv50_pior_dp_func;
return 0;
}
struct nouveau_oclass *
nva0_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x83),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nva0_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nv84_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nva0_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
}.base.base;

View File

@ -0,0 +1,118 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
nva3_disp_sclass[] = {
{ NVA3_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
{ NVA3_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
{ NVA3_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
{ NVA3_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
{ NVA3_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
{}
};
static struct nouveau_omthds
nva3_disp_base_omthds[] = {
{ HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos },
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd },
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd },
{ PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd },
{},
};
static struct nouveau_oclass
nva3_disp_base_oclass[] = {
{ NVA3_DISP_CLASS, &nv50_disp_base_ofuncs, nva3_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int ret;
ret = nouveau_disp_create(parent, engine, oclass, 2, "PDISP",
"display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nva3_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nv50_disp_intr;
INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
priv->sclass = nva3_disp_sclass;
priv->head.nr = 2;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->pior.nr = 3;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hda_eld = nva3_hda_eld;
priv->sor.hdmi = nva3_hdmi_ctrl;
priv->sor.dp = &nv94_sor_dp_func;
priv->pior.power = nv50_pior_power;
priv->pior.dp = &nv50_pior_dp_func;
return 0;
}
struct nouveau_oclass *
nva3_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x85),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nva3_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nv94_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nv84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
}.base.base;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,266 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* EVO master channel object
******************************************************************************/
static const struct nv50_disp_mthd_list
nve0_disp_mast_mthd_head = {
.mthd = 0x0300,
.addr = 0x000300,
.data = {
{ 0x0400, 0x660400 },
{ 0x0404, 0x660404 },
{ 0x0408, 0x660408 },
{ 0x040c, 0x66040c },
{ 0x0410, 0x660410 },
{ 0x0414, 0x660414 },
{ 0x0418, 0x660418 },
{ 0x041c, 0x66041c },
{ 0x0420, 0x660420 },
{ 0x0424, 0x660424 },
{ 0x0428, 0x660428 },
{ 0x042c, 0x66042c },
{ 0x0430, 0x660430 },
{ 0x0434, 0x660434 },
{ 0x0438, 0x660438 },
{ 0x0440, 0x660440 },
{ 0x0444, 0x660444 },
{ 0x0448, 0x660448 },
{ 0x044c, 0x66044c },
{ 0x0450, 0x660450 },
{ 0x0454, 0x660454 },
{ 0x0458, 0x660458 },
{ 0x045c, 0x66045c },
{ 0x0460, 0x660460 },
{ 0x0468, 0x660468 },
{ 0x046c, 0x66046c },
{ 0x0470, 0x660470 },
{ 0x0474, 0x660474 },
{ 0x047c, 0x66047c },
{ 0x0480, 0x660480 },
{ 0x0484, 0x660484 },
{ 0x0488, 0x660488 },
{ 0x048c, 0x66048c },
{ 0x0490, 0x660490 },
{ 0x0494, 0x660494 },
{ 0x0498, 0x660498 },
{ 0x04a0, 0x6604a0 },
{ 0x04b0, 0x6604b0 },
{ 0x04b8, 0x6604b8 },
{ 0x04bc, 0x6604bc },
{ 0x04c0, 0x6604c0 },
{ 0x04c4, 0x6604c4 },
{ 0x04c8, 0x6604c8 },
{ 0x04d0, 0x6604d0 },
{ 0x04d4, 0x6604d4 },
{ 0x04e0, 0x6604e0 },
{ 0x04e4, 0x6604e4 },
{ 0x04e8, 0x6604e8 },
{ 0x04ec, 0x6604ec },
{ 0x04f0, 0x6604f0 },
{ 0x04f4, 0x6604f4 },
{ 0x04f8, 0x6604f8 },
{ 0x04fc, 0x6604fc },
{ 0x0500, 0x660500 },
{ 0x0504, 0x660504 },
{ 0x0508, 0x660508 },
{ 0x050c, 0x66050c },
{ 0x0510, 0x660510 },
{ 0x0514, 0x660514 },
{ 0x0518, 0x660518 },
{ 0x051c, 0x66051c },
{ 0x0520, 0x660520 },
{ 0x0524, 0x660524 },
{ 0x052c, 0x66052c },
{ 0x0530, 0x660530 },
{ 0x054c, 0x66054c },
{ 0x0550, 0x660550 },
{ 0x0554, 0x660554 },
{ 0x0558, 0x660558 },
{ 0x055c, 0x66055c },
{}
}
};
const struct nv50_disp_mthd_chan
nve0_disp_mast_mthd_chan = {
.name = "Core",
.addr = 0x000000,
.data = {
{ "Global", 1, &nvd0_disp_mast_mthd_base },
{ "DAC", 3, &nvd0_disp_mast_mthd_dac },
{ "SOR", 8, &nvd0_disp_mast_mthd_sor },
{ "PIOR", 4, &nvd0_disp_mast_mthd_pior },
{ "HEAD", 4, &nve0_disp_mast_mthd_head },
{}
}
};
/*******************************************************************************
* EVO overlay channel objects
******************************************************************************/
static const struct nv50_disp_mthd_list
nve0_disp_ovly_mthd_base = {
.mthd = 0x0000,
.data = {
{ 0x0080, 0x665080 },
{ 0x0084, 0x665084 },
{ 0x0088, 0x665088 },
{ 0x008c, 0x66508c },
{ 0x0090, 0x665090 },
{ 0x0094, 0x665094 },
{ 0x00a0, 0x6650a0 },
{ 0x00a4, 0x6650a4 },
{ 0x00b0, 0x6650b0 },
{ 0x00b4, 0x6650b4 },
{ 0x00b8, 0x6650b8 },
{ 0x00c0, 0x6650c0 },
{ 0x00c4, 0x6650c4 },
{ 0x00e0, 0x6650e0 },
{ 0x00e4, 0x6650e4 },
{ 0x00e8, 0x6650e8 },
{ 0x0100, 0x665100 },
{ 0x0104, 0x665104 },
{ 0x0108, 0x665108 },
{ 0x010c, 0x66510c },
{ 0x0110, 0x665110 },
{ 0x0118, 0x665118 },
{ 0x011c, 0x66511c },
{ 0x0120, 0x665120 },
{ 0x0124, 0x665124 },
{ 0x0130, 0x665130 },
{ 0x0134, 0x665134 },
{ 0x0138, 0x665138 },
{ 0x013c, 0x66513c },
{ 0x0140, 0x665140 },
{ 0x0144, 0x665144 },
{ 0x0148, 0x665148 },
{ 0x014c, 0x66514c },
{ 0x0150, 0x665150 },
{ 0x0154, 0x665154 },
{ 0x0158, 0x665158 },
{ 0x015c, 0x66515c },
{ 0x0160, 0x665160 },
{ 0x0164, 0x665164 },
{ 0x0168, 0x665168 },
{ 0x016c, 0x66516c },
{ 0x0400, 0x665400 },
{ 0x0404, 0x665404 },
{ 0x0408, 0x665408 },
{ 0x040c, 0x66540c },
{ 0x0410, 0x665410 },
{}
}
};
const struct nv50_disp_mthd_chan
nve0_disp_ovly_mthd_chan = {
.name = "Overlay",
.addr = 0x001000,
.data = {
{ "Global", 1, &nve0_disp_ovly_mthd_base },
{}
}
};
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
nve0_disp_sclass[] = {
{ NVE0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
{ NVE0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
{ NVE0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
{ NVE0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
{ NVE0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
{}
};
static struct nouveau_oclass
nve0_disp_base_oclass[] = {
{ NVE0_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nve0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr;
INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
priv->sclass = nve0_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hda_eld = nvd0_hda_eld;
priv->sor.hdmi = nvd0_hdmi_ctrl;
priv->sor.dp = &nvd0_sor_dp_func;
return 0;
}
struct nouveau_oclass *
nve0_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x91),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nve0_disp_mast_mthd_chan,
.mthd.base = &nvd0_disp_sync_mthd_chan,
.mthd.ovly = &nve0_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
}.base.base;

View File

@ -0,0 +1,101 @@
/*
* 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 <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include "nv50.h"
/*******************************************************************************
* Base display object
******************************************************************************/
static struct nouveau_oclass
nvf0_disp_sclass[] = {
{ NVF0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
{ NVF0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
{ NVF0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
{ NVF0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
{ NVF0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
{}
};
static struct nouveau_oclass
nvf0_disp_base_oclass[] = {
{ NVF0_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds },
{}
};
/*******************************************************************************
* Display engine implementation
******************************************************************************/
static int
nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_disp_priv *priv;
int heads = nv_rd32(parent, 0x022448);
int ret;
ret = nouveau_disp_create(parent, engine, oclass, heads,
"PDISP", "display", &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nvf0_disp_base_oclass;
nv_engine(priv)->cclass = &nv50_disp_cclass;
nv_subdev(priv)->intr = nvd0_disp_intr;
INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
priv->sclass = nvf0_disp_sclass;
priv->head.nr = heads;
priv->dac.nr = 3;
priv->sor.nr = 4;
priv->dac.power = nv50_dac_power;
priv->dac.sense = nv50_dac_sense;
priv->sor.power = nv50_sor_power;
priv->sor.hda_eld = nvd0_hda_eld;
priv->sor.hdmi = nvd0_hdmi_ctrl;
priv->sor.dp = &nvd0_sor_dp_func;
return 0;
}
struct nouveau_oclass *
nvf0_disp_oclass = &(struct nv50_disp_impl) {
.base.base.handle = NV_ENGINE(DISP, 0x92),
.base.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvf0_disp_ctor,
.dtor = _nouveau_disp_dtor,
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.mthd.core = &nve0_disp_mast_mthd_chan,
.mthd.base = &nvd0_disp_sync_mthd_chan,
.mthd.ovly = &nve0_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
}.base.base;

View File

@ -0,0 +1,140 @@
/*
* 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/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
#include <subdev/i2c.h>
#include "nv50.h"
/******************************************************************************
* DisplayPort
*****************************************************************************/
static struct nouveau_i2c_port *
nv50_pior_dp_find(struct nouveau_disp *disp, struct dcb_output *outp)
{
struct nouveau_i2c *i2c = nouveau_i2c(disp);
return i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(outp->extdev));
}
static int
nv50_pior_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int pattern)
{
struct nouveau_i2c_port *port;
int ret = -EINVAL;
port = nv50_pior_dp_find(disp, outp);
if (port) {
if (port->func->pattern)
ret = port->func->pattern(port, pattern);
else
ret = 0;
}
return ret;
}
static int
nv50_pior_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int lane_nr, int link_bw, bool enh)
{
struct nouveau_i2c_port *port;
int ret = -EINVAL;
port = nv50_pior_dp_find(disp, outp);
if (port && port->func->lnk_ctl)
ret = port->func->lnk_ctl(port, lane_nr, link_bw, enh);
return ret;
}
static int
nv50_pior_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int lane, int vsw, int pre)
{
struct nouveau_i2c_port *port;
int ret = -EINVAL;
port = nv50_pior_dp_find(disp, outp);
if (port) {
if (port->func->drv_ctl)
ret = port->func->drv_ctl(port, lane, vsw, pre);
else
ret = 0;
}
return ret;
}
const struct nouveau_dp_func
nv50_pior_dp_func = {
.pattern = nv50_pior_dp_pattern,
.lnk_ctl = nv50_pior_dp_lnk_ctl,
.drv_ctl = nv50_pior_dp_drv_ctl,
};
/******************************************************************************
* General PIOR handling
*****************************************************************************/
int
nv50_pior_power(struct nv50_disp_priv *priv, int or, u32 data)
{
const u32 stat = data & NV50_DISP_PIOR_PWR_STATE;
const u32 soff = (or * 0x800);
nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000);
nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | stat);
nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000);
return 0;
}
int
nv50_pior_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
{
struct nv50_disp_priv *priv = (void *)object->engine;
const u8 type = (mthd & NV50_DISP_PIOR_MTHD_TYPE) >> 12;
const u8 or = (mthd & NV50_DISP_PIOR_MTHD_OR);
u32 *data = args;
int ret;
if (size < sizeof(u32))
return -EINVAL;
mthd &= ~NV50_DISP_PIOR_MTHD_TYPE;
mthd &= ~NV50_DISP_PIOR_MTHD_OR;
switch (mthd) {
case NV50_DISP_PIOR_PWR:
ret = priv->pior.power(priv, or, data[0]);
priv->pior.type[or] = type;
break;
default:
return -EINVAL;
}
return ret;
}

View File

@ -0,0 +1,10 @@
#ifndef __NVKM_DISP_PRIV_H__
#define __NVKM_DISP_PRIV_H__
#include <engine/disp.h>
struct nouveau_disp_impl {
struct nouveau_oclass base;
};
#endif

View File

@ -0,0 +1,79 @@
/*
* 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/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
#include "nv50.h"
int
nv50_sor_power(struct nv50_disp_priv *priv, int or, u32 data)
{
const u32 stat = data & NV50_DISP_SOR_PWR_STATE;
const u32 soff = (or * 0x800);
nv_wait(priv, 0x61c004 + soff, 0x80000000, 0x00000000);
nv_mask(priv, 0x61c004 + soff, 0x80000001, 0x80000000 | stat);
nv_wait(priv, 0x61c004 + soff, 0x80000000, 0x00000000);
nv_wait(priv, 0x61c030 + soff, 0x10000000, 0x00000000);
return 0;
}
int
nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
{
struct nv50_disp_priv *priv = (void *)object->engine;
const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3;
const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR);
u32 data;
int ret = -EINVAL;
if (size < sizeof(u32))
return -EINVAL;
data = *(u32 *)args;
switch (mthd & ~0x3f) {
case NV50_DISP_SOR_PWR:
ret = priv->sor.power(priv, or, data);
break;
case NVA3_DISP_SOR_HDA_ELD:
ret = priv->sor.hda_eld(priv, or, args, size);
break;
case NV84_DISP_SOR_HDMI_PWR:
ret = priv->sor.hdmi(priv, head, or, data);
break;
case NV50_DISP_SOR_LVDS_SCRIPT:
priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID;
ret = 0;
break;
default:
BUG_ON(1);
}
return ret;
}

View File

@ -0,0 +1,131 @@
/*
* 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/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/init.h>
#include "nv50.h"
static inline u32
nv94_sor_soff(struct dcb_output *outp)
{
return (ffs(outp->or) - 1) * 0x800;
}
static inline u32
nv94_sor_loff(struct dcb_output *outp)
{
return nv94_sor_soff(outp) + !(outp->sorconf.link & 1) * 0x80;
}
static inline u32
nv94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
{
static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */
static const u8 nv94[] = { 16, 8, 0, 24 };
if (nv_device(priv)->chipset == 0xaf)
return nvaf[lane];
return nv94[lane];
}
static int
nv94_sor_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int pattern)
{
struct nv50_disp_priv *priv = (void *)disp;
const u32 loff = nv94_sor_loff(outp);
nv_mask(priv, 0x61c10c + loff, 0x0f000000, pattern << 24);
return 0;
}
static int
nv94_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int link_nr, int link_bw, bool enh_frame)
{
struct nv50_disp_priv *priv = (void *)disp;
const u32 soff = nv94_sor_soff(outp);
const u32 loff = nv94_sor_loff(outp);
u32 dpctrl = 0x00000000;
u32 clksor = 0x00000000;
u32 lane = 0;
int i;
dpctrl |= ((1 << link_nr) - 1) << 16;
if (enh_frame)
dpctrl |= 0x00004000;
if (link_bw > 0x06)
clksor |= 0x00040000;
for (i = 0; i < link_nr; i++)
lane |= 1 << (nv94_sor_dp_lane_map(priv, i) >> 3);
nv_mask(priv, 0x614300 + soff, 0x000c0000, clksor);
nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl);
nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane);
return 0;
}
static int
nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int lane, int swing, int preem)
{
struct nouveau_bios *bios = nouveau_bios(disp);
struct nv50_disp_priv *priv = (void *)disp;
const u32 shift = nv94_sor_dp_lane_map(priv, lane);
const u32 loff = nv94_sor_loff(outp);
u32 addr, data[3];
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
struct nvbios_dpcfg ocfg;
addr = nvbios_dpout_match(bios, outp->hasht, outp->hashm,
&ver, &hdr, &cnt, &len, &info);
if (!addr)
return -ENODEV;
addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem,
&ver, &hdr, &cnt, &len, &ocfg);
if (!addr)
return -EINVAL;
data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00);
nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift));
nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift));
nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8));
return 0;
}
const struct nouveau_dp_func
nv94_sor_dp_func = {
.pattern = nv94_sor_dp_pattern,
.lnk_ctl = nv94_sor_dp_lnk_ctl,
.drv_ctl = nv94_sor_dp_drv_ctl,
};

View File

@ -0,0 +1,128 @@
/*
* 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/os.h>
#include <core/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h>
#include <subdev/bios/init.h>
#include "nv50.h"
static inline u32
nvd0_sor_soff(struct dcb_output *outp)
{
return (ffs(outp->or) - 1) * 0x800;
}
static inline u32
nvd0_sor_loff(struct dcb_output *outp)
{
return nvd0_sor_soff(outp) + !(outp->sorconf.link & 1) * 0x80;
}
static inline u32
nvd0_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
{
static const u8 nvd0[] = { 16, 8, 0, 24 };
return nvd0[lane];
}
static int
nvd0_sor_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int pattern)
{
struct nv50_disp_priv *priv = (void *)disp;
const u32 loff = nvd0_sor_loff(outp);
nv_mask(priv, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
return 0;
}
static int
nvd0_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int link_nr, int link_bw, bool enh_frame)
{
struct nv50_disp_priv *priv = (void *)disp;
const u32 soff = nvd0_sor_soff(outp);
const u32 loff = nvd0_sor_loff(outp);
u32 dpctrl = 0x00000000;
u32 clksor = 0x00000000;
u32 lane = 0;
int i;
clksor |= link_bw << 18;
dpctrl |= ((1 << link_nr) - 1) << 16;
if (enh_frame)
dpctrl |= 0x00004000;
for (i = 0; i < link_nr; i++)
lane |= 1 << (nvd0_sor_dp_lane_map(priv, i) >> 3);
nv_mask(priv, 0x612300 + soff, 0x007c0000, clksor);
nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl);
nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane);
return 0;
}
static int
nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp,
int head, int lane, int swing, int preem)
{
struct nouveau_bios *bios = nouveau_bios(disp);
struct nv50_disp_priv *priv = (void *)disp;
const u32 shift = nvd0_sor_dp_lane_map(priv, lane);
const u32 loff = nvd0_sor_loff(outp);
u32 addr, data[3];
u8 ver, hdr, cnt, len;
struct nvbios_dpout info;
struct nvbios_dpcfg ocfg;
addr = nvbios_dpout_match(bios, outp->hasht, outp->hashm,
&ver, &hdr, &cnt, &len, &info);
if (!addr)
return -ENODEV;
addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem,
&ver, &hdr, &cnt, &len, &ocfg);
if (!addr)
return -EINVAL;
data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00);
nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift));
nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift));
nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8));
nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000);
return 0;
}
const struct nouveau_dp_func
nvd0_sor_dp_func = {
.pattern = nvd0_sor_dp_pattern,
.lnk_ctl = nvd0_sor_dp_lnk_ctl,
.drv_ctl = nvd0_sor_dp_drv_ctl,
};

View File

@ -0,0 +1,220 @@
/*
* 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/subdev.h>
#include <core/device.h>
#include <subdev/vga.h>
u8
nv_rdport(void *obj, int head, u16 port)
{
struct nouveau_device *device = nv_device(obj);
if (device->card_type >= NV_50)
return nv_rd08(obj, 0x601000 + port);
if (port == 0x03c0 || port == 0x03c1 || /* AR */
port == 0x03c2 || port == 0x03da || /* INP0 */
port == 0x03d4 || port == 0x03d5) /* CR */
return nv_rd08(obj, 0x601000 + (head * 0x2000) + port);
if (port == 0x03c2 || port == 0x03cc || /* MISC */
port == 0x03c4 || port == 0x03c5 || /* SR */
port == 0x03ce || port == 0x03cf) { /* GR */
if (device->card_type < NV_40)
head = 0; /* CR44 selects head */
return nv_rd08(obj, 0x0c0000 + (head * 0x2000) + port);
}
nv_error(obj, "unknown vga port 0x%04x\n", port);
return 0x00;
}
void
nv_wrport(void *obj, int head, u16 port, u8 data)
{
struct nouveau_device *device = nv_device(obj);
if (device->card_type >= NV_50)
nv_wr08(obj, 0x601000 + port, data);
else
if (port == 0x03c0 || port == 0x03c1 || /* AR */
port == 0x03c2 || port == 0x03da || /* INP0 */
port == 0x03d4 || port == 0x03d5) /* CR */
nv_wr08(obj, 0x601000 + (head * 0x2000) + port, data);
else
if (port == 0x03c2 || port == 0x03cc || /* MISC */
port == 0x03c4 || port == 0x03c5 || /* SR */
port == 0x03ce || port == 0x03cf) { /* GR */
if (device->card_type < NV_40)
head = 0; /* CR44 selects head */
nv_wr08(obj, 0x0c0000 + (head * 0x2000) + port, data);
} else
nv_error(obj, "unknown vga port 0x%04x\n", port);
}
u8
nv_rdvgas(void *obj, int head, u8 index)
{
nv_wrport(obj, head, 0x03c4, index);
return nv_rdport(obj, head, 0x03c5);
}
void
nv_wrvgas(void *obj, int head, u8 index, u8 value)
{
nv_wrport(obj, head, 0x03c4, index);
nv_wrport(obj, head, 0x03c5, value);
}
u8
nv_rdvgag(void *obj, int head, u8 index)
{
nv_wrport(obj, head, 0x03ce, index);
return nv_rdport(obj, head, 0x03cf);
}
void
nv_wrvgag(void *obj, int head, u8 index, u8 value)
{
nv_wrport(obj, head, 0x03ce, index);
nv_wrport(obj, head, 0x03cf, value);
}
u8
nv_rdvgac(void *obj, int head, u8 index)
{
nv_wrport(obj, head, 0x03d4, index);
return nv_rdport(obj, head, 0x03d5);
}
void
nv_wrvgac(void *obj, int head, u8 index, u8 value)
{
nv_wrport(obj, head, 0x03d4, index);
nv_wrport(obj, head, 0x03d5, value);
}
u8
nv_rdvgai(void *obj, int head, u16 port, u8 index)
{
if (port == 0x03c4) return nv_rdvgas(obj, head, index);
if (port == 0x03ce) return nv_rdvgag(obj, head, index);
if (port == 0x03d4) return nv_rdvgac(obj, head, index);
nv_error(obj, "unknown indexed vga port 0x%04x\n", port);
return 0x00;
}
void
nv_wrvgai(void *obj, int head, u16 port, u8 index, u8 value)
{
if (port == 0x03c4) nv_wrvgas(obj, head, index, value);
else if (port == 0x03ce) nv_wrvgag(obj, head, index, value);
else if (port == 0x03d4) nv_wrvgac(obj, head, index, value);
else nv_error(obj, "unknown indexed vga port 0x%04x\n", port);
}
bool
nv_lockvgac(void *obj, bool lock)
{
struct nouveau_device *dev = nv_device(obj);
bool locked = !nv_rdvgac(obj, 0, 0x1f);
u8 data = lock ? 0x99 : 0x57;
if (dev->card_type < NV_50)
nv_wrvgac(obj, 0, 0x1f, data);
else
nv_wrvgac(obj, 0, 0x3f, data);
if (dev->chipset == 0x11) {
if (!(nv_rd32(obj, 0x001084) & 0x10000000))
nv_wrvgac(obj, 1, 0x1f, data);
}
return locked;
}
/* CR44 takes values 0 (head A), 3 (head B) and 4 (heads tied)
* it affects only the 8 bit vga io regs, which we access using mmio at
* 0xc{0,2}3c*, 0x60{1,3}3*, and 0x68{1,3}3d*
* in general, the set value of cr44 does not matter: reg access works as
* expected and values can be set for the appropriate head by using a 0x2000
* offset as required
* however:
* a) pre nv40, the head B range of PRMVIO regs at 0xc23c* was not exposed and
* cr44 must be set to 0 or 3 for accessing values on the correct head
* through the common 0xc03c* addresses
* b) in tied mode (4) head B is programmed to the values set on head A, and
* access using the head B addresses can have strange results, ergo we leave
* tied mode in init once we know to what cr44 should be restored on exit
*
* the owner parameter is slightly abused:
* 0 and 1 are treated as head values and so the set value is (owner * 3)
* other values are treated as literal values to set
*/
u8
nv_rdvgaowner(void *obj)
{
if (nv_device(obj)->card_type < NV_50) {
if (nv_device(obj)->chipset == 0x11) {
u32 tied = nv_rd32(obj, 0x001084) & 0x10000000;
if (tied == 0) {
u8 slA = nv_rdvgac(obj, 0, 0x28) & 0x80;
u8 tvA = nv_rdvgac(obj, 0, 0x33) & 0x01;
u8 slB = nv_rdvgac(obj, 1, 0x28) & 0x80;
u8 tvB = nv_rdvgac(obj, 1, 0x33) & 0x01;
if (slA && !tvA) return 0x00;
if (slB && !tvB) return 0x03;
if (slA) return 0x00;
if (slB) return 0x03;
return 0x00;
}
return 0x04;
}
return nv_rdvgac(obj, 0, 0x44);
}
nv_error(obj, "rdvgaowner after nv4x\n");
return 0x00;
}
void
nv_wrvgaowner(void *obj, u8 select)
{
if (nv_device(obj)->card_type < NV_50) {
u8 owner = (select == 1) ? 3 : select;
if (nv_device(obj)->chipset == 0x11) {
/* workaround hw lockup bug */
nv_rdvgac(obj, 0, 0x1f);
nv_rdvgac(obj, 1, 0x1f);
}
nv_wrvgac(obj, 0, 0x44, owner);
if (nv_device(obj)->chipset == 0x11) {
nv_wrvgac(obj, 0, 0x2e, owner);
nv_wrvgac(obj, 0, 0x2e, owner);
}
} else
nv_error(obj, "wrvgaowner after nv4x\n");
}

View File

@ -0,0 +1,120 @@
/*
* 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/object.h>
#include <core/class.h>
#include <subdev/fb.h>
#include <engine/dmaobj.h>
static int
nouveau_dmaobj_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_dmaeng *dmaeng = (void *)engine;
struct nouveau_dmaobj *dmaobj;
struct nouveau_gpuobj *gpuobj;
struct nv_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_object_create(parent, engine, oclass, 0, &dmaobj);
*pobject = nv_object(dmaobj);
if (ret)
return ret;
switch (args->flags & NV_DMA_TARGET_MASK) {
case NV_DMA_TARGET_VM:
dmaobj->target = NV_MEM_TARGET_VM;
break;
case NV_DMA_TARGET_VRAM:
dmaobj->target = NV_MEM_TARGET_VRAM;
break;
case NV_DMA_TARGET_PCI:
dmaobj->target = NV_MEM_TARGET_PCI;
break;
case NV_DMA_TARGET_PCI_US:
case NV_DMA_TARGET_AGP:
dmaobj->target = NV_MEM_TARGET_PCI_NOSNOOP;
break;
default:
return -EINVAL;
}
switch (args->flags & NV_DMA_ACCESS_MASK) {
case NV_DMA_ACCESS_VM:
dmaobj->access = NV_MEM_ACCESS_VM;
break;
case NV_DMA_ACCESS_RD:
dmaobj->access = NV_MEM_ACCESS_RO;
break;
case NV_DMA_ACCESS_WR:
dmaobj->access = NV_MEM_ACCESS_WO;
break;
case NV_DMA_ACCESS_RDWR:
dmaobj->access = NV_MEM_ACCESS_RW;
break;
default:
return -EINVAL;
}
dmaobj->start = args->start;
dmaobj->limit = args->limit;
dmaobj->conf0 = args->conf0;
switch (nv_mclass(parent)) {
case NV_DEVICE_CLASS:
/* delayed, or no, binding */
break;
default:
ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj);
if (ret == 0) {
nouveau_object_ref(NULL, pobject);
*pobject = nv_object(gpuobj);
}
break;
}
return ret;
}
static struct nouveau_ofuncs
nouveau_dmaobj_ofuncs = {
.ctor = nouveau_dmaobj_ctor,
.dtor = nouveau_object_destroy,
.init = nouveau_object_init,
.fini = nouveau_object_fini,
};
struct nouveau_oclass
nouveau_dmaobj_sclass[] = {
{ NV_DMA_FROM_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
{ NV_DMA_TO_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
{ NV_DMA_IN_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
{}
};

View File

@ -0,0 +1,143 @@
/*
* 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/gpuobj.h>
#include <core/class.h>
#include <subdev/fb.h>
#include <subdev/vm/nv04.h>
#include <engine/dmaobj.h>
struct nv04_dmaeng_priv {
struct nouveau_dmaeng base;
};
static int
nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
struct nouveau_object *parent,
struct nouveau_dmaobj *dmaobj,
struct nouveau_gpuobj **pgpuobj)
{
struct nv04_vmmgr_priv *vmm = nv04_vmmgr(dmaeng);
struct nouveau_gpuobj *gpuobj;
u32 flags0 = nv_mclass(dmaobj);
u32 flags2 = 0x00000000;
u64 offset = dmaobj->start & 0xfffff000;
u64 adjust = dmaobj->start & 0x00000fff;
u32 length = dmaobj->limit - dmaobj->start;
int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NV03_CHANNEL_DMA_CLASS:
case NV10_CHANNEL_DMA_CLASS:
case NV17_CHANNEL_DMA_CLASS:
case NV40_CHANNEL_DMA_CLASS:
break;
default:
return -EINVAL;
}
}
if (dmaobj->target == NV_MEM_TARGET_VM) {
if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) {
struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0];
if (!dmaobj->start)
return nouveau_gpuobj_dup(parent, pgt, pgpuobj);
offset = nv_ro32(pgt, 8 + (offset >> 10));
offset &= 0xfffff000;
}
dmaobj->target = NV_MEM_TARGET_PCI;
dmaobj->access = NV_MEM_ACCESS_RW;
}
switch (dmaobj->target) {
case NV_MEM_TARGET_VRAM:
flags0 |= 0x00003000;
break;
case NV_MEM_TARGET_PCI:
flags0 |= 0x00023000;
break;
case NV_MEM_TARGET_PCI_NOSNOOP:
flags0 |= 0x00033000;
break;
default:
return -EINVAL;
}
switch (dmaobj->access) {
case NV_MEM_ACCESS_RO:
flags0 |= 0x00004000;
break;
case NV_MEM_ACCESS_WO:
flags0 |= 0x00008000;
case NV_MEM_ACCESS_RW:
flags2 |= 0x00000002;
break;
default:
return -EINVAL;
}
ret = nouveau_gpuobj_new(parent, parent, 16, 16, 0, &gpuobj);
*pgpuobj = gpuobj;
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, flags0 | (adjust << 20));
nv_wo32(*pgpuobj, 0x04, length);
nv_wo32(*pgpuobj, 0x08, flags2 | offset);
nv_wo32(*pgpuobj, 0x0c, flags2 | offset);
}
return ret;
}
static int
nv04_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_dmaeng_priv *priv;
int ret;
ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nouveau_dmaobj_sclass;
priv->base.bind = nv04_dmaobj_bind;
return 0;
}
struct nouveau_oclass
nv04_dmaeng_oclass = {
.handle = NV_ENGINE(DMAOBJ, 0x04),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_dmaeng_ctor,
.dtor = _nouveau_dmaeng_dtor,
.init = _nouveau_dmaeng_init,
.fini = _nouveau_dmaeng_fini,
},
};

View File

@ -0,0 +1,161 @@
/*
* 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/gpuobj.h>
#include <core/class.h>
#include <subdev/fb.h>
#include <engine/dmaobj.h>
struct nv50_dmaeng_priv {
struct nouveau_dmaeng base;
};
static int
nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
struct nouveau_object *parent,
struct nouveau_dmaobj *dmaobj,
struct nouveau_gpuobj **pgpuobj)
{
u32 flags0 = nv_mclass(dmaobj);
u32 flags5 = 0x00000000;
int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NV50_CHANNEL_DMA_CLASS:
case NV84_CHANNEL_DMA_CLASS:
case NV50_CHANNEL_IND_CLASS:
case NV84_CHANNEL_IND_CLASS:
case NV50_DISP_MAST_CLASS:
case NV84_DISP_MAST_CLASS:
case NV94_DISP_MAST_CLASS:
case NVA0_DISP_MAST_CLASS:
case NVA3_DISP_MAST_CLASS:
case NV50_DISP_SYNC_CLASS:
case NV84_DISP_SYNC_CLASS:
case NV94_DISP_SYNC_CLASS:
case NVA0_DISP_SYNC_CLASS:
case NVA3_DISP_SYNC_CLASS:
case NV50_DISP_OVLY_CLASS:
case NV84_DISP_OVLY_CLASS:
case NV94_DISP_OVLY_CLASS:
case NVA0_DISP_OVLY_CLASS:
case NVA3_DISP_OVLY_CLASS:
break;
default:
return -EINVAL;
}
}
if (!(dmaobj->conf0 & NV50_DMA_CONF0_ENABLE)) {
if (dmaobj->target == NV_MEM_TARGET_VM) {
dmaobj->conf0 = NV50_DMA_CONF0_PRIV_VM;
dmaobj->conf0 |= NV50_DMA_CONF0_PART_VM;
dmaobj->conf0 |= NV50_DMA_CONF0_COMP_VM;
dmaobj->conf0 |= NV50_DMA_CONF0_TYPE_VM;
} else {
dmaobj->conf0 = NV50_DMA_CONF0_PRIV_US;
dmaobj->conf0 |= NV50_DMA_CONF0_PART_256;
dmaobj->conf0 |= NV50_DMA_CONF0_COMP_NONE;
dmaobj->conf0 |= NV50_DMA_CONF0_TYPE_LINEAR;
}
}
flags0 |= (dmaobj->conf0 & NV50_DMA_CONF0_COMP) << 22;
flags0 |= (dmaobj->conf0 & NV50_DMA_CONF0_TYPE) << 22;
flags0 |= (dmaobj->conf0 & NV50_DMA_CONF0_PRIV);
flags5 |= (dmaobj->conf0 & NV50_DMA_CONF0_PART);
switch (dmaobj->target) {
case NV_MEM_TARGET_VM:
flags0 |= 0x00000000;
break;
case NV_MEM_TARGET_VRAM:
flags0 |= 0x00010000;
break;
case NV_MEM_TARGET_PCI:
flags0 |= 0x00020000;
break;
case NV_MEM_TARGET_PCI_NOSNOOP:
flags0 |= 0x00030000;
break;
default:
return -EINVAL;
}
switch (dmaobj->access) {
case NV_MEM_ACCESS_VM:
break;
case NV_MEM_ACCESS_RO:
flags0 |= 0x00040000;
break;
case NV_MEM_ACCESS_WO:
case NV_MEM_ACCESS_RW:
flags0 |= 0x00080000;
break;
}
ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, flags0);
nv_wo32(*pgpuobj, 0x04, lower_32_bits(dmaobj->limit));
nv_wo32(*pgpuobj, 0x08, lower_32_bits(dmaobj->start));
nv_wo32(*pgpuobj, 0x0c, upper_32_bits(dmaobj->limit) << 24 |
upper_32_bits(dmaobj->start));
nv_wo32(*pgpuobj, 0x10, 0x00000000);
nv_wo32(*pgpuobj, 0x14, flags5);
}
return ret;
}
static int
nv50_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_dmaeng_priv *priv;
int ret;
ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nouveau_dmaobj_sclass;
priv->base.bind = nv50_dmaobj_bind;
return 0;
}
struct nouveau_oclass
nv50_dmaeng_oclass = {
.handle = NV_ENGINE(DMAOBJ, 0x50),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_dmaeng_ctor,
.dtor = _nouveau_dmaeng_dtor,
.init = _nouveau_dmaeng_init,
.fini = _nouveau_dmaeng_fini,
},
};

View File

@ -0,0 +1,143 @@
/*
* 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/device.h>
#include <core/gpuobj.h>
#include <core/class.h>
#include <subdev/fb.h>
#include <engine/dmaobj.h>
struct nvc0_dmaeng_priv {
struct nouveau_dmaeng base;
};
static int
nvc0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
struct nouveau_object *parent,
struct nouveau_dmaobj *dmaobj,
struct nouveau_gpuobj **pgpuobj)
{
u32 flags0 = nv_mclass(dmaobj);
u32 flags5 = 0x00000000;
int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NVA3_DISP_MAST_CLASS:
case NVA3_DISP_SYNC_CLASS:
case NVA3_DISP_OVLY_CLASS:
break;
default:
return -EINVAL;
}
} else
return 0;
if (!(dmaobj->conf0 & NVC0_DMA_CONF0_ENABLE)) {
if (dmaobj->target == NV_MEM_TARGET_VM) {
dmaobj->conf0 = NVC0_DMA_CONF0_PRIV_VM;
dmaobj->conf0 |= NVC0_DMA_CONF0_TYPE_VM;
} else {
dmaobj->conf0 = NVC0_DMA_CONF0_PRIV_US;
dmaobj->conf0 |= NVC0_DMA_CONF0_TYPE_LINEAR;
dmaobj->conf0 |= 0x00020000;
}
}
flags0 |= (dmaobj->conf0 & NVC0_DMA_CONF0_TYPE) << 22;
flags0 |= (dmaobj->conf0 & NVC0_DMA_CONF0_PRIV);
flags5 |= (dmaobj->conf0 & NVC0_DMA_CONF0_UNKN);
switch (dmaobj->target) {
case NV_MEM_TARGET_VM:
flags0 |= 0x00000000;
break;
case NV_MEM_TARGET_VRAM:
flags0 |= 0x00010000;
break;
case NV_MEM_TARGET_PCI:
flags0 |= 0x00020000;
break;
case NV_MEM_TARGET_PCI_NOSNOOP:
flags0 |= 0x00030000;
break;
default:
return -EINVAL;
}
switch (dmaobj->access) {
case NV_MEM_ACCESS_VM:
break;
case NV_MEM_ACCESS_RO:
flags0 |= 0x00040000;
break;
case NV_MEM_ACCESS_WO:
case NV_MEM_ACCESS_RW:
flags0 |= 0x00080000;
break;
}
ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, flags0);
nv_wo32(*pgpuobj, 0x04, lower_32_bits(dmaobj->limit));
nv_wo32(*pgpuobj, 0x08, lower_32_bits(dmaobj->start));
nv_wo32(*pgpuobj, 0x0c, upper_32_bits(dmaobj->limit) << 24 |
upper_32_bits(dmaobj->start));
nv_wo32(*pgpuobj, 0x10, 0x00000000);
nv_wo32(*pgpuobj, 0x14, flags5);
}
return ret;
}
static int
nvc0_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvc0_dmaeng_priv *priv;
int ret;
ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nouveau_dmaobj_sclass;
priv->base.bind = nvc0_dmaobj_bind;
return 0;
}
struct nouveau_oclass
nvc0_dmaeng_oclass = {
.handle = NV_ENGINE(DMAOBJ, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_dmaeng_ctor,
.dtor = _nouveau_dmaeng_dtor,
.init = _nouveau_dmaeng_init,
.fini = _nouveau_dmaeng_fini,
},
};

View File

@ -0,0 +1,128 @@
/*
* 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/device.h>
#include <core/gpuobj.h>
#include <core/class.h>
#include <subdev/fb.h>
#include <engine/dmaobj.h>
struct nvd0_dmaeng_priv {
struct nouveau_dmaeng base;
};
static int
nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
struct nouveau_object *parent,
struct nouveau_dmaobj *dmaobj,
struct nouveau_gpuobj **pgpuobj)
{
u32 flags0 = 0x00000000;
int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NVD0_DISP_MAST_CLASS:
case NVD0_DISP_SYNC_CLASS:
case NVD0_DISP_OVLY_CLASS:
case NVE0_DISP_MAST_CLASS:
case NVE0_DISP_SYNC_CLASS:
case NVE0_DISP_OVLY_CLASS:
case NVF0_DISP_MAST_CLASS:
case NVF0_DISP_SYNC_CLASS:
case NVF0_DISP_OVLY_CLASS:
case GM107_DISP_MAST_CLASS:
case GM107_DISP_SYNC_CLASS:
case GM107_DISP_OVLY_CLASS:
break;
default:
return -EINVAL;
}
} else
return 0;
if (!(dmaobj->conf0 & NVD0_DMA_CONF0_ENABLE)) {
if (dmaobj->target == NV_MEM_TARGET_VM) {
dmaobj->conf0 |= NVD0_DMA_CONF0_TYPE_VM;
dmaobj->conf0 |= NVD0_DMA_CONF0_PAGE_LP;
} else {
dmaobj->conf0 |= NVD0_DMA_CONF0_TYPE_LINEAR;
dmaobj->conf0 |= NVD0_DMA_CONF0_PAGE_SP;
}
}
flags0 |= (dmaobj->conf0 & NVD0_DMA_CONF0_TYPE) << 20;
flags0 |= (dmaobj->conf0 & NVD0_DMA_CONF0_PAGE) >> 4;
switch (dmaobj->target) {
case NV_MEM_TARGET_VRAM:
flags0 |= 0x00000009;
break;
default:
return -EINVAL;
break;
}
ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj);
if (ret == 0) {
nv_wo32(*pgpuobj, 0x00, flags0);
nv_wo32(*pgpuobj, 0x04, dmaobj->start >> 8);
nv_wo32(*pgpuobj, 0x08, dmaobj->limit >> 8);
nv_wo32(*pgpuobj, 0x0c, 0x00000000);
nv_wo32(*pgpuobj, 0x10, 0x00000000);
nv_wo32(*pgpuobj, 0x14, 0x00000000);
}
return ret;
}
static int
nvd0_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvd0_dmaeng_priv *priv;
int ret;
ret = nouveau_dmaeng_create(parent, engine, oclass, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nv_engine(priv)->sclass = nouveau_dmaobj_sclass;
priv->base.bind = nvd0_dmaobj_bind;
return 0;
}
struct nouveau_oclass
nvd0_dmaeng_oclass = {
.handle = NV_ENGINE(DMAOBJ, 0xd0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvd0_dmaeng_ctor,
.dtor = _nouveau_dmaeng_dtor,
.init = _nouveau_dmaeng_init,
.fini = _nouveau_dmaeng_fini,
},
};

View File

@ -0,0 +1,278 @@
/*
* 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.
*/
#include <engine/falcon.h>
#include <subdev/timer.h>
void
nouveau_falcon_intr(struct nouveau_subdev *subdev)
{
struct nouveau_falcon *falcon = (void *)subdev;
u32 dispatch = nv_ro32(falcon, 0x01c);
u32 intr = nv_ro32(falcon, 0x008) & dispatch & ~(dispatch >> 16);
if (intr & 0x00000010) {
nv_debug(falcon, "ucode halted\n");
nv_wo32(falcon, 0x004, 0x00000010);
intr &= ~0x00000010;
}
if (intr) {
nv_error(falcon, "unhandled intr 0x%08x\n", intr);
nv_wo32(falcon, 0x004, intr);
}
}
u32
_nouveau_falcon_rd32(struct nouveau_object *object, u64 addr)
{
struct nouveau_falcon *falcon = (void *)object;
return nv_rd32(falcon, falcon->addr + addr);
}
void
_nouveau_falcon_wr32(struct nouveau_object *object, u64 addr, u32 data)
{
struct nouveau_falcon *falcon = (void *)object;
nv_wr32(falcon, falcon->addr + addr, data);
}
static void *
vmemdup(const void *src, size_t len)
{
void *p = vmalloc(len);
if (p)
memcpy(p, src, len);
return p;
}
int
_nouveau_falcon_init(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
struct nouveau_falcon *falcon = (void *)object;
const struct firmware *fw;
char name[32] = "internal";
int ret, i;
u32 caps;
/* enable engine, and determine its capabilities */
ret = nouveau_engine_init(&falcon->base);
if (ret)
return ret;
if (device->chipset < 0xa3 ||
device->chipset == 0xaa || device->chipset == 0xac) {
falcon->version = 0;
falcon->secret = (falcon->addr == 0x087000) ? 1 : 0;
} else {
caps = nv_ro32(falcon, 0x12c);
falcon->version = (caps & 0x0000000f);
falcon->secret = (caps & 0x00000030) >> 4;
}
caps = nv_ro32(falcon, 0x108);
falcon->code.limit = (caps & 0x000001ff) << 8;
falcon->data.limit = (caps & 0x0003fe00) >> 1;
nv_debug(falcon, "falcon version: %d\n", falcon->version);
nv_debug(falcon, "secret level: %d\n", falcon->secret);
nv_debug(falcon, "code limit: %d\n", falcon->code.limit);
nv_debug(falcon, "data limit: %d\n", falcon->data.limit);
/* wait for 'uc halted' to be signalled before continuing */
if (falcon->secret && falcon->version < 4) {
if (!falcon->version)
nv_wait(falcon, 0x008, 0x00000010, 0x00000010);
else
nv_wait(falcon, 0x180, 0x80000000, 0);
nv_wo32(falcon, 0x004, 0x00000010);
}
/* disable all interrupts */
nv_wo32(falcon, 0x014, 0xffffffff);
/* no default ucode provided by the engine implementation, try and
* locate a "self-bootstrapping" firmware image for the engine
*/
if (!falcon->code.data) {
snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03x",
device->chipset, falcon->addr >> 12);
ret = request_firmware(&fw, name, nv_device_base(device));
if (ret == 0) {
falcon->code.data = vmemdup(fw->data, fw->size);
falcon->code.size = fw->size;
falcon->data.data = NULL;
falcon->data.size = 0;
release_firmware(fw);
}
falcon->external = true;
}
/* next step is to try and load "static code/data segment" firmware
* images for the engine
*/
if (!falcon->code.data) {
snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xd",
device->chipset, falcon->addr >> 12);
ret = request_firmware(&fw, name, nv_device_base(device));
if (ret) {
nv_error(falcon, "unable to load firmware data\n");
return ret;
}
falcon->data.data = vmemdup(fw->data, fw->size);
falcon->data.size = fw->size;
release_firmware(fw);
if (!falcon->data.data)
return -ENOMEM;
snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xc",
device->chipset, falcon->addr >> 12);
ret = request_firmware(&fw, name, nv_device_base(device));
if (ret) {
nv_error(falcon, "unable to load firmware code\n");
return ret;
}
falcon->code.data = vmemdup(fw->data, fw->size);
falcon->code.size = fw->size;
release_firmware(fw);
if (!falcon->code.data)
return -ENOMEM;
}
nv_debug(falcon, "firmware: %s (%s)\n", name, falcon->data.data ?
"static code/data segments" : "self-bootstrapping");
/* ensure any "self-bootstrapping" firmware image is in vram */
if (!falcon->data.data && !falcon->core) {
ret = nouveau_gpuobj_new(object->parent, NULL,
falcon->code.size, 256, 0,
&falcon->core);
if (ret) {
nv_error(falcon, "core allocation failed, %d\n", ret);
return ret;
}
for (i = 0; i < falcon->code.size; i += 4)
nv_wo32(falcon->core, i, falcon->code.data[i / 4]);
}
/* upload firmware bootloader (or the full code segments) */
if (falcon->core) {
if (device->card_type < NV_C0)
nv_wo32(falcon, 0x618, 0x04000000);
else
nv_wo32(falcon, 0x618, 0x00000114);
nv_wo32(falcon, 0x11c, 0);
nv_wo32(falcon, 0x110, falcon->core->addr >> 8);
nv_wo32(falcon, 0x114, 0);
nv_wo32(falcon, 0x118, 0x00006610);
} else {
if (falcon->code.size > falcon->code.limit ||
falcon->data.size > falcon->data.limit) {
nv_error(falcon, "ucode exceeds falcon limit(s)\n");
return -EINVAL;
}
if (falcon->version < 3) {
nv_wo32(falcon, 0xff8, 0x00100000);
for (i = 0; i < falcon->code.size / 4; i++)
nv_wo32(falcon, 0xff4, falcon->code.data[i]);
} else {
nv_wo32(falcon, 0x180, 0x01000000);
for (i = 0; i < falcon->code.size / 4; i++) {
if ((i & 0x3f) == 0)
nv_wo32(falcon, 0x188, i >> 6);
nv_wo32(falcon, 0x184, falcon->code.data[i]);
}
}
}
/* upload data segment (if necessary), zeroing the remainder */
if (falcon->version < 3) {
nv_wo32(falcon, 0xff8, 0x00000000);
for (i = 0; !falcon->core && i < falcon->data.size / 4; i++)
nv_wo32(falcon, 0xff4, falcon->data.data[i]);
for (; i < falcon->data.limit; i += 4)
nv_wo32(falcon, 0xff4, 0x00000000);
} else {
nv_wo32(falcon, 0x1c0, 0x01000000);
for (i = 0; !falcon->core && i < falcon->data.size / 4; i++)
nv_wo32(falcon, 0x1c4, falcon->data.data[i]);
for (; i < falcon->data.limit / 4; i++)
nv_wo32(falcon, 0x1c4, 0x00000000);
}
/* start it running */
nv_wo32(falcon, 0x10c, 0x00000001); /* BLOCK_ON_FIFO */
nv_wo32(falcon, 0x104, 0x00000000); /* ENTRY */
nv_wo32(falcon, 0x100, 0x00000002); /* TRIGGER */
nv_wo32(falcon, 0x048, 0x00000003); /* FIFO | CHSW */
return 0;
}
int
_nouveau_falcon_fini(struct nouveau_object *object, bool suspend)
{
struct nouveau_falcon *falcon = (void *)object;
if (!suspend) {
nouveau_gpuobj_ref(NULL, &falcon->core);
if (falcon->external) {
vfree(falcon->data.data);
vfree(falcon->code.data);
falcon->code.data = NULL;
}
}
nv_mo32(falcon, 0x048, 0x00000003, 0x00000000);
nv_wo32(falcon, 0x014, 0xffffffff);
return nouveau_engine_fini(&falcon->base, suspend);
}
int
nouveau_falcon_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, u32 addr, bool enable,
const char *iname, const char *fname,
int length, void **pobject)
{
struct nouveau_falcon *falcon;
int ret;
ret = nouveau_engine_create_(parent, engine, oclass, enable, iname,
fname, length, pobject);
falcon = *pobject;
if (ret)
return ret;
falcon->addr = addr;
return 0;
}

View File

@ -0,0 +1,208 @@
/*
* 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/client.h>
#include <core/object.h>
#include <core/handle.h>
#include <core/event.h>
#include <core/class.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
int
nouveau_fifo_channel_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass,
int bar, u32 addr, u32 size, u32 pushbuf,
u64 engmask, int len, void **ptr)
{
struct nouveau_device *device = nv_device(engine);
struct nouveau_fifo *priv = (void *)engine;
struct nouveau_fifo_chan *chan;
struct nouveau_dmaeng *dmaeng;
unsigned long flags;
int ret;
/* create base object class */
ret = nouveau_namedb_create_(parent, engine, oclass, 0, NULL,
engmask, len, ptr);
chan = *ptr;
if (ret)
return ret;
/* validate dma object representing push buffer */
chan->pushdma = (void *)nouveau_handle_ref(parent, pushbuf);
if (!chan->pushdma)
return -ENOENT;
dmaeng = (void *)chan->pushdma->base.engine;
switch (chan->pushdma->base.oclass->handle) {
case NV_DMA_FROM_MEMORY_CLASS:
case NV_DMA_IN_MEMORY_CLASS:
break;
default:
return -EINVAL;
}
ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu);
if (ret)
return ret;
/* find a free fifo channel */
spin_lock_irqsave(&priv->lock, flags);
for (chan->chid = priv->min; chan->chid < priv->max; chan->chid++) {
if (!priv->channel[chan->chid]) {
priv->channel[chan->chid] = nv_object(chan);
break;
}
}
spin_unlock_irqrestore(&priv->lock, flags);
if (chan->chid == priv->max) {
nv_error(priv, "no free channels\n");
return -ENOSPC;
}
/* map fifo control registers */
chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
(chan->chid * size), size);
if (!chan->user)
return -EFAULT;
nouveau_event_trigger(priv->cevent, 0);
chan->size = size;
return 0;
}
void
nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *chan)
{
struct nouveau_fifo *priv = (void *)nv_object(chan)->engine;
unsigned long flags;
iounmap(chan->user);
spin_lock_irqsave(&priv->lock, flags);
priv->channel[chan->chid] = NULL;
spin_unlock_irqrestore(&priv->lock, flags);
nouveau_gpuobj_ref(NULL, &chan->pushgpu);
nouveau_object_ref(NULL, (struct nouveau_object **)&chan->pushdma);
nouveau_namedb_destroy(&chan->base);
}
void
_nouveau_fifo_channel_dtor(struct nouveau_object *object)
{
struct nouveau_fifo_chan *chan = (void *)object;
nouveau_fifo_channel_destroy(chan);
}
u32
_nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr)
{
struct nouveau_fifo_chan *chan = (void *)object;
return ioread32_native(chan->user + addr);
}
void
_nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
{
struct nouveau_fifo_chan *chan = (void *)object;
iowrite32_native(data, chan->user + addr);
}
static int
nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object)
{
int engidx = nv_hclass(priv) & 0xff;
while (object && object->parent) {
if ( nv_iclass(object->parent, NV_ENGCTX_CLASS) &&
(nv_hclass(object->parent) & 0xff) == engidx)
return nouveau_fifo_chan(object)->chid;
object = object->parent;
}
return -1;
}
const char *
nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid)
{
struct nouveau_fifo_chan *chan = NULL;
unsigned long flags;
spin_lock_irqsave(&fifo->lock, flags);
if (chid >= fifo->min && chid <= fifo->max)
chan = (void *)fifo->channel[chid];
spin_unlock_irqrestore(&fifo->lock, flags);
return nouveau_client_name(chan);
}
void
nouveau_fifo_destroy(struct nouveau_fifo *priv)
{
kfree(priv->channel);
nouveau_event_destroy(&priv->uevent);
nouveau_event_destroy(&priv->cevent);
nouveau_engine_destroy(&priv->base);
}
int
nouveau_fifo_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass,
int min, int max, int length, void **pobject)
{
struct nouveau_fifo *priv;
int ret;
ret = nouveau_engine_create_(parent, engine, oclass, true, "PFIFO",
"fifo", length, pobject);
priv = *pobject;
if (ret)
return ret;
priv->min = min;
priv->max = max;
priv->channel = kzalloc(sizeof(*priv->channel) * (max + 1), GFP_KERNEL);
if (!priv->channel)
return -ENOMEM;
ret = nouveau_event_create(1, &priv->cevent);
if (ret)
return ret;
ret = nouveau_event_create(1, &priv->uevent);
if (ret)
return ret;
priv->chid = nouveau_fifo_chid;
spin_lock_init(&priv->lock);
return 0;
}

View File

@ -0,0 +1,644 @@
/*
* 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/os.h>
#include <core/class.h>
#include <core/engctx.h>
#include <core/namedb.h>
#include <core/handle.h>
#include <core/ramht.h>
#include <core/event.h>
#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <engine/fifo.h>
#include "nv04.h"
static struct ramfc_desc
nv04_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 16, 0, 0x08, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
{ 16, 16, 0x08, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
{ 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_STATE },
{ 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
{ 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_ENGINE },
{ 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_PULL1 },
{}
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
int
nv04_fifo_object_attach(struct nouveau_object *parent,
struct nouveau_object *object, u32 handle)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
u32 context, chid = chan->base.chid;
int ret;
if (nv_iclass(object, NV_GPUOBJ_CLASS))
context = nv_gpuobj(object)->addr >> 4;
else
context = 0x00000004; /* just non-zero */
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_DMAOBJ:
case NVDEV_ENGINE_SW:
context |= 0x00000000;
break;
case NVDEV_ENGINE_GR:
context |= 0x00010000;
break;
case NVDEV_ENGINE_MPEG:
context |= 0x00020000;
break;
default:
return -EINVAL;
}
context |= 0x80000000; /* valid */
context |= chid << 24;
mutex_lock(&nv_subdev(priv)->mutex);
ret = nouveau_ramht_insert(priv->ramht, chid, handle, context);
mutex_unlock(&nv_subdev(priv)->mutex);
return ret;
}
void
nv04_fifo_object_detach(struct nouveau_object *parent, int cookie)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
mutex_lock(&nv_subdev(priv)->mutex);
nouveau_ramht_remove(priv->ramht, cookie);
mutex_unlock(&nv_subdev(priv)->mutex);
}
int
nv04_fifo_context_attach(struct nouveau_object *parent,
struct nouveau_object *object)
{
nv_engctx(object)->addr = nouveau_fifo_chan(parent)->chid;
return 0;
}
static int
nv04_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
0x10000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->object_attach = nv04_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
nv_parent(chan)->context_attach = nv04_fifo_context_attach;
chan->ramfc = chan->base.chid * 32;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x08, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x10,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
return 0;
}
void
nv04_fifo_chan_dtor(struct nouveau_object *object)
{
struct nv04_fifo_priv *priv = (void *)object->engine;
struct nv04_fifo_chan *chan = (void *)object;
struct ramfc_desc *c = priv->ramfc_desc;
do {
nv_wo32(priv->ramfc, chan->ramfc + c->ctxp, 0x00000000);
} while ((++c)->bits);
nouveau_fifo_channel_destroy(&chan->base);
}
int
nv04_fifo_chan_init(struct nouveau_object *object)
{
struct nv04_fifo_priv *priv = (void *)object->engine;
struct nv04_fifo_chan *chan = (void *)object;
u32 mask = 1 << chan->base.chid;
unsigned long flags;
int ret;
ret = nouveau_fifo_channel_init(&chan->base);
if (ret)
return ret;
spin_lock_irqsave(&priv->base.lock, flags);
nv_mask(priv, NV04_PFIFO_MODE, mask, mask);
spin_unlock_irqrestore(&priv->base.lock, flags);
return 0;
}
int
nv04_fifo_chan_fini(struct nouveau_object *object, bool suspend)
{
struct nv04_fifo_priv *priv = (void *)object->engine;
struct nv04_fifo_chan *chan = (void *)object;
struct nouveau_gpuobj *fctx = priv->ramfc;
struct ramfc_desc *c;
unsigned long flags;
u32 data = chan->ramfc;
u32 chid;
/* prevent fifo context switches */
spin_lock_irqsave(&priv->base.lock, flags);
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
/* if this channel is active, replace it with a null context */
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
if (chid == chan->base.chid) {
nv_mask(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 0);
nv_mask(priv, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
c = priv->ramfc_desc;
do {
u32 rm = ((1ULL << c->bits) - 1) << c->regs;
u32 cm = ((1ULL << c->bits) - 1) << c->ctxs;
u32 rv = (nv_rd32(priv, c->regp) & rm) >> c->regs;
u32 cv = (nv_ro32(fctx, c->ctxp + data) & ~cm);
nv_wo32(fctx, c->ctxp + data, cv | (rv << c->ctxs));
} while ((++c)->bits);
c = priv->ramfc_desc;
do {
nv_wr32(priv, c->regp, 0x00000000);
} while ((++c)->bits);
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, 0);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUT, 0);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
}
/* restore normal operation, after disabling dma mode */
nv_mask(priv, NV04_PFIFO_MODE, 1 << chan->base.chid, 0);
nv_wr32(priv, NV03_PFIFO_CACHES, 1);
spin_unlock_irqrestore(&priv->base.lock, flags);
return nouveau_fifo_channel_fini(&chan->base, suspend);
}
static struct nouveau_ofuncs
nv04_fifo_ofuncs = {
.ctor = nv04_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nv04_fifo_sclass[] = {
{ NV03_CHANNEL_DMA_CLASS, &nv04_fifo_ofuncs },
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
int
nv04_fifo_context_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_fifo_base *base;
int ret;
ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
0x1000, NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
return 0;
}
static struct nouveau_oclass
nv04_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x04),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fifo_context_ctor,
.dtor = _nouveau_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
void
nv04_fifo_pause(struct nouveau_fifo *pfifo, unsigned long *pflags)
__acquires(priv->base.lock)
{
struct nv04_fifo_priv *priv = (void *)pfifo;
unsigned long flags;
spin_lock_irqsave(&priv->base.lock, flags);
*pflags = flags;
nv_wr32(priv, NV03_PFIFO_CACHES, 0x00000000);
nv_mask(priv, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0x00000000);
/* in some cases the puller may be left in an inconsistent state
* if you try to stop it while it's busy translating handles.
* sometimes you get a CACHE_ERROR, sometimes it just fails
* silently; sending incorrect instance offsets to PGRAPH after
* it's started up again.
*
* to avoid this, we invalidate the most recently calculated
* instance.
*/
if (!nv_wait(priv, NV04_PFIFO_CACHE1_PULL0,
NV04_PFIFO_CACHE1_PULL0_HASH_BUSY, 0x00000000))
nv_warn(priv, "timeout idling puller\n");
if (nv_rd32(priv, NV04_PFIFO_CACHE1_PULL0) &
NV04_PFIFO_CACHE1_PULL0_HASH_FAILED)
nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
nv_wr32(priv, NV04_PFIFO_CACHE1_HASH, 0x00000000);
}
void
nv04_fifo_start(struct nouveau_fifo *pfifo, unsigned long *pflags)
__releases(priv->base.lock)
{
struct nv04_fifo_priv *priv = (void *)pfifo;
unsigned long flags = *pflags;
nv_mask(priv, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0x00000001);
nv_wr32(priv, NV03_PFIFO_CACHES, 0x00000001);
spin_unlock_irqrestore(&priv->base.lock, flags);
}
static const char *
nv_dma_state_err(u32 state)
{
static const char * const desc[] = {
"NONE", "CALL_SUBR_ACTIVE", "INVALID_MTHD", "RET_SUBR_INACTIVE",
"INVALID_CMD", "IB_EMPTY"/* NV50+ */, "MEM_FAULT", "UNK"
};
return desc[(state >> 29) & 0x7];
}
static bool
nv04_fifo_swmthd(struct nv04_fifo_priv *priv, u32 chid, u32 addr, u32 data)
{
struct nv04_fifo_chan *chan = NULL;
struct nouveau_handle *bind;
const int subc = (addr >> 13) & 0x7;
const int mthd = addr & 0x1ffc;
bool handled = false;
unsigned long flags;
u32 engine;
spin_lock_irqsave(&priv->base.lock, flags);
if (likely(chid >= priv->base.min && chid <= priv->base.max))
chan = (void *)priv->base.channel[chid];
if (unlikely(!chan))
goto out;
switch (mthd) {
case 0x0000:
bind = nouveau_namedb_get(nv_namedb(chan), data);
if (unlikely(!bind))
break;
if (nv_engidx(bind->object->engine) == NVDEV_ENGINE_SW) {
engine = 0x0000000f << (subc * 4);
chan->subc[subc] = data;
handled = true;
nv_mask(priv, NV04_PFIFO_CACHE1_ENGINE, engine, 0);
}
nouveau_namedb_put(bind);
break;
default:
engine = nv_rd32(priv, NV04_PFIFO_CACHE1_ENGINE);
if (unlikely(((engine >> (subc * 4)) & 0xf) != 0))
break;
bind = nouveau_namedb_get(nv_namedb(chan), chan->subc[subc]);
if (likely(bind)) {
if (!nv_call(bind->object, mthd, data))
handled = true;
nouveau_namedb_put(bind);
}
break;
}
out:
spin_unlock_irqrestore(&priv->base.lock, flags);
return handled;
}
static void
nv04_fifo_cache_error(struct nouveau_device *device,
struct nv04_fifo_priv *priv, u32 chid, u32 get)
{
u32 mthd, data;
int ptr;
/* NV_PFIFO_CACHE1_GET actually goes to 0xffc before wrapping on my
* G80 chips, but CACHE1 isn't big enough for this much data.. Tests
* show that it wraps around to the start at GET=0x800.. No clue as to
* why..
*/
ptr = (get & 0x7ff) >> 2;
if (device->card_type < NV_40) {
mthd = nv_rd32(priv, NV04_PFIFO_CACHE1_METHOD(ptr));
data = nv_rd32(priv, NV04_PFIFO_CACHE1_DATA(ptr));
} else {
mthd = nv_rd32(priv, NV40_PFIFO_CACHE1_METHOD(ptr));
data = nv_rd32(priv, NV40_PFIFO_CACHE1_DATA(ptr));
}
if (!nv04_fifo_swmthd(priv, chid, mthd, data)) {
const char *client_name =
nouveau_client_name_for_fifo_chid(&priv->base, chid);
nv_error(priv,
"CACHE_ERROR - ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
chid, client_name, (mthd >> 13) & 7, mthd & 0x1ffc,
data);
}
nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH, 0);
nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_CACHE_ERROR);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0,
nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) & ~1);
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0,
nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH0) | 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_HASH, 0);
nv_wr32(priv, NV04_PFIFO_CACHE1_DMA_PUSH,
nv_rd32(priv, NV04_PFIFO_CACHE1_DMA_PUSH) | 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
}
static void
nv04_fifo_dma_pusher(struct nouveau_device *device, struct nv04_fifo_priv *priv,
u32 chid)
{
const char *client_name;
u32 dma_get = nv_rd32(priv, 0x003244);
u32 dma_put = nv_rd32(priv, 0x003240);
u32 push = nv_rd32(priv, 0x003220);
u32 state = nv_rd32(priv, 0x003228);
client_name = nouveau_client_name_for_fifo_chid(&priv->base, chid);
if (device->card_type == NV_50) {
u32 ho_get = nv_rd32(priv, 0x003328);
u32 ho_put = nv_rd32(priv, 0x003320);
u32 ib_get = nv_rd32(priv, 0x003334);
u32 ib_put = nv_rd32(priv, 0x003330);
nv_error(priv,
"DMA_PUSHER - ch %d [%s] get 0x%02x%08x put 0x%02x%08x ib_get 0x%08x ib_put 0x%08x state 0x%08x (err: %s) push 0x%08x\n",
chid, client_name, ho_get, dma_get, ho_put, dma_put,
ib_get, ib_put, state, nv_dma_state_err(state), push);
/* METHOD_COUNT, in DMA_STATE on earlier chipsets */
nv_wr32(priv, 0x003364, 0x00000000);
if (dma_get != dma_put || ho_get != ho_put) {
nv_wr32(priv, 0x003244, dma_put);
nv_wr32(priv, 0x003328, ho_put);
} else
if (ib_get != ib_put)
nv_wr32(priv, 0x003334, ib_put);
} else {
nv_error(priv,
"DMA_PUSHER - ch %d [%s] get 0x%08x put 0x%08x state 0x%08x (err: %s) push 0x%08x\n",
chid, client_name, dma_get, dma_put, state,
nv_dma_state_err(state), push);
if (dma_get != dma_put)
nv_wr32(priv, 0x003244, dma_put);
}
nv_wr32(priv, 0x003228, 0x00000000);
nv_wr32(priv, 0x003220, 0x00000001);
nv_wr32(priv, 0x002100, NV_PFIFO_INTR_DMA_PUSHER);
}
void
nv04_fifo_intr(struct nouveau_subdev *subdev)
{
struct nouveau_device *device = nv_device(subdev);
struct nv04_fifo_priv *priv = (void *)subdev;
uint32_t status, reassign;
int cnt = 0;
reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
uint32_t chid, get;
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
if (status & NV_PFIFO_INTR_CACHE_ERROR) {
nv04_fifo_cache_error(device, priv, chid, get);
status &= ~NV_PFIFO_INTR_CACHE_ERROR;
}
if (status & NV_PFIFO_INTR_DMA_PUSHER) {
nv04_fifo_dma_pusher(device, priv, chid);
status &= ~NV_PFIFO_INTR_DMA_PUSHER;
}
if (status & NV_PFIFO_INTR_SEMAPHORE) {
uint32_t sem;
status &= ~NV_PFIFO_INTR_SEMAPHORE;
nv_wr32(priv, NV03_PFIFO_INTR_0,
NV_PFIFO_INTR_SEMAPHORE);
sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
}
if (device->card_type == NV_50) {
if (status & 0x00000010) {
status &= ~0x00000010;
nv_wr32(priv, 0x002100, 0x00000010);
}
if (status & 0x40000000) {
nouveau_event_trigger(priv->base.uevent, 0);
nv_wr32(priv, 0x002100, 0x40000000);
status &= ~0x40000000;
}
}
if (status) {
nv_warn(priv, "unknown intr 0x%08x, ch %d\n",
status, chid);
nv_wr32(priv, NV03_PFIFO_INTR_0, status);
status = 0;
}
nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
}
if (status) {
nv_error(priv, "still angry after %d spins, halt\n", cnt);
nv_wr32(priv, 0x002140, 0);
nv_wr32(priv, 0x000140, 0);
}
nv_wr32(priv, 0x000100, 0x00000100);
}
static int
nv04_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 15, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nouveau_ramht_ref(imem->ramht, &priv->ramht);
nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv04_fifo_cclass;
nv_engine(priv)->sclass = nv04_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
priv->ramfc_desc = nv04_ramfc;
return 0;
}
void
nv04_fifo_dtor(struct nouveau_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
nouveau_gpuobj_ref(NULL, &priv->ramfc);
nouveau_gpuobj_ref(NULL, &priv->ramro);
nouveau_ramht_ref(NULL, &priv->ramht);
nouveau_fifo_destroy(&priv->base);
}
int
nv04_fifo_init(struct nouveau_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
int ret;
ret = nouveau_fifo_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, NV04_PFIFO_DELAY_0, 0x000000ff);
nv_wr32(priv, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
((priv->ramht->bits - 9) << 16) |
(priv->ramht->base.addr >> 8));
nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
nv_wr32(priv, NV03_PFIFO_RAMFC, priv->ramfc->addr >> 8);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
nv_wr32(priv, NV03_PFIFO_INTR_0, 0xffffffff);
nv_wr32(priv, NV03_PFIFO_INTR_EN_0, 0xffffffff);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
nv_wr32(priv, NV03_PFIFO_CACHES, 1);
return 0;
}
struct nouveau_oclass *
nv04_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0x04),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv04_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

View File

@ -0,0 +1,178 @@
#ifndef __NV04_FIFO_H__
#define __NV04_FIFO_H__
#include <engine/fifo.h>
#define NV04_PFIFO_DELAY_0 0x00002040
#define NV04_PFIFO_DMA_TIMESLICE 0x00002044
#define NV04_PFIFO_NEXT_CHANNEL 0x00002050
#define NV03_PFIFO_INTR_0 0x00002100
#define NV03_PFIFO_INTR_EN_0 0x00002140
# define NV_PFIFO_INTR_CACHE_ERROR (1<<0)
# define NV_PFIFO_INTR_RUNOUT (1<<4)
# define NV_PFIFO_INTR_RUNOUT_OVERFLOW (1<<8)
# define NV_PFIFO_INTR_DMA_PUSHER (1<<12)
# define NV_PFIFO_INTR_DMA_PT (1<<16)
# define NV_PFIFO_INTR_SEMAPHORE (1<<20)
# define NV_PFIFO_INTR_ACQUIRE_TIMEOUT (1<<24)
#define NV03_PFIFO_RAMHT 0x00002210
#define NV03_PFIFO_RAMFC 0x00002214
#define NV03_PFIFO_RAMRO 0x00002218
#define NV40_PFIFO_RAMFC 0x00002220
#define NV03_PFIFO_CACHES 0x00002500
#define NV04_PFIFO_MODE 0x00002504
#define NV04_PFIFO_DMA 0x00002508
#define NV04_PFIFO_SIZE 0x0000250c
#define NV50_PFIFO_CTX_TABLE(c) (0x2600+(c)*4)
#define NV50_PFIFO_CTX_TABLE__SIZE 128
#define NV50_PFIFO_CTX_TABLE_CHANNEL_ENABLED (1<<31)
#define NV50_PFIFO_CTX_TABLE_UNK30_BAD (1<<30)
#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G80 0x0FFFFFFF
#define NV50_PFIFO_CTX_TABLE_INSTANCE_MASK_G84 0x00FFFFFF
#define NV03_PFIFO_CACHE0_PUSH0 0x00003000
#define NV03_PFIFO_CACHE0_PULL0 0x00003040
#define NV04_PFIFO_CACHE0_PULL0 0x00003050
#define NV04_PFIFO_CACHE0_PULL1 0x00003054
#define NV03_PFIFO_CACHE1_PUSH0 0x00003200
#define NV03_PFIFO_CACHE1_PUSH1 0x00003204
#define NV03_PFIFO_CACHE1_PUSH1_DMA (1<<8)
#define NV40_PFIFO_CACHE1_PUSH1_DMA (1<<16)
#define NV03_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000000f
#define NV10_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000001f
#define NV50_PFIFO_CACHE1_PUSH1_CHID_MASK 0x0000007f
#define NV03_PFIFO_CACHE1_PUT 0x00003210
#define NV04_PFIFO_CACHE1_DMA_PUSH 0x00003220
#define NV04_PFIFO_CACHE1_DMA_FETCH 0x00003224
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000008
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000010
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000018
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000020
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000028
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000030
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000038
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000040
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000048
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x00000050
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x00000058
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x00000060
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x00000068
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x00000070
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x00000078
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000080
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000088
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000090
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000098
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x000000A0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x000000A8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x000000B0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x000000B8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x000000C0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x000000C8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x000000D0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x000000D8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x000000E0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x000000E8
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x000000F0
# define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x000000F8
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 0x0000E000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00002000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00004000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00006000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00008000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x0000A000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x0000C000
# define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x0000E000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 0x001F0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00010000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00020000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00030000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00040000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00050000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00060000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00070000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00080000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00090000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x000A0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x000B0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x000C0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x000D0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x000E0000
# define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x000F0000
# define NV_PFIFO_CACHE1_ENDIAN 0x80000000
# define NV_PFIFO_CACHE1_LITTLE_ENDIAN 0x7FFFFFFF
# define NV_PFIFO_CACHE1_BIG_ENDIAN 0x80000000
#define NV04_PFIFO_CACHE1_DMA_STATE 0x00003228
#define NV04_PFIFO_CACHE1_DMA_INSTANCE 0x0000322c
#define NV04_PFIFO_CACHE1_DMA_CTL 0x00003230
#define NV04_PFIFO_CACHE1_DMA_PUT 0x00003240
#define NV04_PFIFO_CACHE1_DMA_GET 0x00003244
#define NV10_PFIFO_CACHE1_REF_CNT 0x00003248
#define NV10_PFIFO_CACHE1_DMA_SUBROUTINE 0x0000324C
#define NV03_PFIFO_CACHE1_PULL0 0x00003240
#define NV04_PFIFO_CACHE1_PULL0 0x00003250
# define NV04_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000010
# define NV04_PFIFO_CACHE1_PULL0_HASH_BUSY 0x00001000
#define NV03_PFIFO_CACHE1_PULL1 0x00003250
#define NV04_PFIFO_CACHE1_PULL1 0x00003254
#define NV04_PFIFO_CACHE1_HASH 0x00003258
#define NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT 0x00003260
#define NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP 0x00003264
#define NV10_PFIFO_CACHE1_ACQUIRE_VALUE 0x00003268
#define NV10_PFIFO_CACHE1_SEMAPHORE 0x0000326C
#define NV03_PFIFO_CACHE1_GET 0x00003270
#define NV04_PFIFO_CACHE1_ENGINE 0x00003280
#define NV04_PFIFO_CACHE1_DMA_DCOUNT 0x000032A0
#define NV40_PFIFO_GRCTX_INSTANCE 0x000032E0
#define NV40_PFIFO_UNK32E4 0x000032E4
#define NV04_PFIFO_CACHE1_METHOD(i) (0x00003800+(i*8))
#define NV04_PFIFO_CACHE1_DATA(i) (0x00003804+(i*8))
#define NV40_PFIFO_CACHE1_METHOD(i) (0x00090000+(i*8))
#define NV40_PFIFO_CACHE1_DATA(i) (0x00090004+(i*8))
struct ramfc_desc {
unsigned bits:6;
unsigned ctxs:5;
unsigned ctxp:8;
unsigned regs:5;
unsigned regp;
};
struct nv04_fifo_priv {
struct nouveau_fifo base;
struct ramfc_desc *ramfc_desc;
struct nouveau_ramht *ramht;
struct nouveau_gpuobj *ramro;
struct nouveau_gpuobj *ramfc;
};
struct nv04_fifo_base {
struct nouveau_fifo_base base;
};
struct nv04_fifo_chan {
struct nouveau_fifo_chan base;
u32 subc[8];
u32 ramfc;
};
int nv04_fifo_object_attach(struct nouveau_object *,
struct nouveau_object *, u32);
void nv04_fifo_object_detach(struct nouveau_object *, int);
void nv04_fifo_chan_dtor(struct nouveau_object *);
int nv04_fifo_chan_init(struct nouveau_object *);
int nv04_fifo_chan_fini(struct nouveau_object *, bool suspend);
int nv04_fifo_context_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, void *, u32,
struct nouveau_object **);
void nv04_fifo_dtor(struct nouveau_object *);
int nv04_fifo_init(struct nouveau_object *);
void nv04_fifo_pause(struct nouveau_fifo *, unsigned long *);
void nv04_fifo_start(struct nouveau_fifo *, unsigned long *);
#endif

View File

@ -0,0 +1,171 @@
/*
* 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/os.h>
#include <core/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
#include <subdev/fb.h>
#include <engine/fifo.h>
#include "nv04.h"
static struct ramfc_desc
nv10_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
{ 16, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
{ 16, 16, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
{ 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_STATE },
{ 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
{ 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_ENGINE },
{ 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_PULL1 },
{}
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static int
nv10_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
0x10000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->object_attach = nv04_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
nv_parent(chan)->context_attach = nv04_fifo_context_attach;
chan->ramfc = chan->base.chid * 32;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x14,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
return 0;
}
static struct nouveau_ofuncs
nv10_fifo_ofuncs = {
.ctor = nv10_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nv10_fifo_sclass[] = {
{ NV10_CHANNEL_DMA_CLASS, &nv10_fifo_ofuncs },
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
static struct nouveau_oclass
nv10_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x10),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fifo_context_ctor,
.dtor = _nouveau_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static int
nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nouveau_ramht_ref(imem->ramht, &priv->ramht);
nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv10_fifo_cclass;
nv_engine(priv)->sclass = nv10_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
priv->ramfc_desc = nv10_ramfc;
return 0;
}
struct nouveau_oclass *
nv10_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0x10),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv10_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv04_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

View File

@ -0,0 +1,37 @@
/*
* 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
*/
#include "nve0.h"
struct nouveau_oclass *
nv108_fifo_oclass = &(struct nve0_fifo_impl) {
.base.handle = NV_ENGINE(FIFO, 0x08),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nve0_fifo_ctor,
.dtor = nve0_fifo_dtor,
.init = nve0_fifo_init,
.fini = _nouveau_fifo_fini,
},
.channels = 1024,
}.base;

View File

@ -0,0 +1,208 @@
/*
* 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/os.h>
#include <core/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
#include <subdev/fb.h>
#include <engine/fifo.h>
#include "nv04.h"
static struct ramfc_desc
nv17_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
{ 16, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
{ 16, 16, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
{ 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_STATE },
{ 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
{ 32, 0, 0x18, 0, NV04_PFIFO_CACHE1_ENGINE },
{ 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_PULL1 },
{ 32, 0, 0x20, 0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
{ 32, 0, 0x24, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
{ 32, 0, 0x28, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
{ 32, 0, 0x2c, 0, NV10_PFIFO_CACHE1_SEMAPHORE },
{ 32, 0, 0x30, 0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
{}
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static int
nv17_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000,
0x10000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_MPEG), /* NV31- */
&chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->object_attach = nv04_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
nv_parent(chan)->context_attach = nv04_fifo_context_attach;
chan->ramfc = chan->base.chid * 64;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x14,
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
return 0;
}
static struct nouveau_ofuncs
nv17_fifo_ofuncs = {
.ctor = nv17_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nv17_fifo_sclass[] = {
{ NV17_CHANNEL_DMA_CLASS, &nv17_fifo_ofuncs },
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
static struct nouveau_oclass
nv17_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x17),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fifo_context_ctor,
.dtor = _nouveau_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static int
nv17_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nouveau_ramht_ref(imem->ramht, &priv->ramht);
nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv17_fifo_cclass;
nv_engine(priv)->sclass = nv17_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
priv->ramfc_desc = nv17_ramfc;
return 0;
}
static int
nv17_fifo_init(struct nouveau_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
int ret;
ret = nouveau_fifo_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, NV04_PFIFO_DELAY_0, 0x000000ff);
nv_wr32(priv, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
((priv->ramht->bits - 9) << 16) |
(priv->ramht->base.addr >> 8));
nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
nv_wr32(priv, NV03_PFIFO_RAMFC, priv->ramfc->addr >> 8 | 0x00010000);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
nv_wr32(priv, NV03_PFIFO_INTR_0, 0xffffffff);
nv_wr32(priv, NV03_PFIFO_INTR_EN_0, 0xffffffff);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
nv_wr32(priv, NV03_PFIFO_CACHES, 1);
return 0;
}
struct nouveau_oclass *
nv17_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0x17),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv17_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv17_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

View File

@ -0,0 +1,349 @@
/*
* 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/os.h>
#include <core/class.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <subdev/instmem.h>
#include <subdev/instmem/nv04.h>
#include <subdev/fb.h>
#include <engine/fifo.h>
#include "nv04.h"
static struct ramfc_desc
nv40_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
{ 32, 0, 0x0c, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
{ 32, 0, 0x10, 0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
{ 32, 0, 0x14, 0, NV04_PFIFO_CACHE1_DMA_STATE },
{ 28, 0, 0x18, 0, NV04_PFIFO_CACHE1_DMA_FETCH },
{ 2, 28, 0x18, 28, 0x002058 },
{ 32, 0, 0x1c, 0, NV04_PFIFO_CACHE1_ENGINE },
{ 32, 0, 0x20, 0, NV04_PFIFO_CACHE1_PULL1 },
{ 32, 0, 0x24, 0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
{ 32, 0, 0x28, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
{ 32, 0, 0x2c, 0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
{ 32, 0, 0x30, 0, NV10_PFIFO_CACHE1_SEMAPHORE },
{ 32, 0, 0x34, 0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
{ 32, 0, 0x38, 0, NV40_PFIFO_GRCTX_INSTANCE },
{ 17, 0, 0x3c, 0, NV04_PFIFO_DMA_TIMESLICE },
{ 32, 0, 0x40, 0, 0x0032e4 },
{ 32, 0, 0x44, 0, 0x0032e8 },
{ 32, 0, 0x4c, 0, 0x002088 },
{ 32, 0, 0x50, 0, 0x003300 },
{ 32, 0, 0x54, 0, 0x00330c },
{}
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static int
nv40_fifo_object_attach(struct nouveau_object *parent,
struct nouveau_object *object, u32 handle)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
u32 context, chid = chan->base.chid;
int ret;
if (nv_iclass(object, NV_GPUOBJ_CLASS))
context = nv_gpuobj(object)->addr >> 4;
else
context = 0x00000004; /* just non-zero */
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_DMAOBJ:
case NVDEV_ENGINE_SW:
context |= 0x00000000;
break;
case NVDEV_ENGINE_GR:
context |= 0x00100000;
break;
case NVDEV_ENGINE_MPEG:
context |= 0x00200000;
break;
default:
return -EINVAL;
}
context |= chid << 23;
mutex_lock(&nv_subdev(priv)->mutex);
ret = nouveau_ramht_insert(priv->ramht, chid, handle, context);
mutex_unlock(&nv_subdev(priv)->mutex);
return ret;
}
static int
nv40_fifo_context_attach(struct nouveau_object *parent,
struct nouveau_object *engctx)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
unsigned long flags;
u32 reg, ctx;
switch (nv_engidx(engctx->engine)) {
case NVDEV_ENGINE_SW:
return 0;
case NVDEV_ENGINE_GR:
reg = 0x32e0;
ctx = 0x38;
break;
case NVDEV_ENGINE_MPEG:
reg = 0x330c;
ctx = 0x54;
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&priv->base.lock, flags);
nv_engctx(engctx)->addr = nv_gpuobj(engctx)->addr >> 4;
nv_mask(priv, 0x002500, 0x00000001, 0x00000000);
if ((nv_rd32(priv, 0x003204) & priv->base.max) == chan->base.chid)
nv_wr32(priv, reg, nv_engctx(engctx)->addr);
nv_wo32(priv->ramfc, chan->ramfc + ctx, nv_engctx(engctx)->addr);
nv_mask(priv, 0x002500, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&priv->base.lock, flags);
return 0;
}
static int
nv40_fifo_context_detach(struct nouveau_object *parent, bool suspend,
struct nouveau_object *engctx)
{
struct nv04_fifo_priv *priv = (void *)parent->engine;
struct nv04_fifo_chan *chan = (void *)parent;
unsigned long flags;
u32 reg, ctx;
switch (nv_engidx(engctx->engine)) {
case NVDEV_ENGINE_SW:
return 0;
case NVDEV_ENGINE_GR:
reg = 0x32e0;
ctx = 0x38;
break;
case NVDEV_ENGINE_MPEG:
reg = 0x330c;
ctx = 0x54;
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&priv->base.lock, flags);
nv_mask(priv, 0x002500, 0x00000001, 0x00000000);
if ((nv_rd32(priv, 0x003204) & priv->base.max) == chan->base.chid)
nv_wr32(priv, reg, 0x00000000);
nv_wo32(priv->ramfc, chan->ramfc + ctx, 0x00000000);
nv_mask(priv, 0x002500, 0x00000001, 0x00000001);
spin_unlock_irqrestore(&priv->base.lock, flags);
return 0;
}
static int
nv40_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_fifo_priv *priv = (void *)engine;
struct nv04_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x1000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_MPEG), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->context_attach = nv40_fifo_context_attach;
nv_parent(chan)->context_detach = nv40_fifo_context_detach;
nv_parent(chan)->object_attach = nv40_fifo_object_attach;
nv_parent(chan)->object_detach = nv04_fifo_object_detach;
chan->ramfc = chan->base.chid * 128;
nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset);
nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4);
nv_wo32(priv->ramfc, chan->ramfc + 0x18, 0x30000000 |
NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
#ifdef __BIG_ENDIAN
NV_PFIFO_CACHE1_BIG_ENDIAN |
#endif
NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
nv_wo32(priv->ramfc, chan->ramfc + 0x3c, 0x0001ffff);
return 0;
}
static struct nouveau_ofuncs
nv40_fifo_ofuncs = {
.ctor = nv40_fifo_chan_ctor,
.dtor = nv04_fifo_chan_dtor,
.init = nv04_fifo_chan_init,
.fini = nv04_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nv40_fifo_sclass[] = {
{ NV40_CHANNEL_DMA_CLASS, &nv40_fifo_ofuncs },
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
static struct nouveau_oclass
nv40_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x40),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv04_fifo_context_ctor,
.dtor = _nouveau_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static int
nv40_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv04_instmem_priv *imem = nv04_instmem(parent);
struct nv04_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 31, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
nouveau_ramht_ref(imem->ramht, &priv->ramht);
nouveau_gpuobj_ref(imem->ramro, &priv->ramro);
nouveau_gpuobj_ref(imem->ramfc, &priv->ramfc);
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv40_fifo_cclass;
nv_engine(priv)->sclass = nv40_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
priv->ramfc_desc = nv40_ramfc;
return 0;
}
static int
nv40_fifo_init(struct nouveau_object *object)
{
struct nv04_fifo_priv *priv = (void *)object;
struct nouveau_fb *pfb = nouveau_fb(object);
int ret;
ret = nouveau_fifo_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x002040, 0x000000ff);
nv_wr32(priv, 0x002044, 0x2101ffff);
nv_wr32(priv, 0x002058, 0x00000001);
nv_wr32(priv, NV03_PFIFO_RAMHT, (0x03 << 24) /* search 128 */ |
((priv->ramht->bits - 9) << 16) |
(priv->ramht->base.addr >> 8));
nv_wr32(priv, NV03_PFIFO_RAMRO, priv->ramro->addr >> 8);
switch (nv_device(priv)->chipset) {
case 0x47:
case 0x49:
case 0x4b:
nv_wr32(priv, 0x002230, 0x00000001);
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x45:
case 0x48:
nv_wr32(priv, 0x002220, 0x00030002);
break;
default:
nv_wr32(priv, 0x002230, 0x00000000);
nv_wr32(priv, 0x002220, ((pfb->ram->size - 512 * 1024 +
priv->ramfc->addr) >> 16) |
0x00030000);
break;
}
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH1, priv->base.max);
nv_wr32(priv, NV03_PFIFO_INTR_0, 0xffffffff);
nv_wr32(priv, NV03_PFIFO_INTR_EN_0, 0xffffffff);
nv_wr32(priv, NV03_PFIFO_CACHE1_PUSH0, 1);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
nv_wr32(priv, NV03_PFIFO_CACHES, 1);
return 0;
}
struct nouveau_oclass *
nv40_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0x40),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv40_fifo_ctor,
.dtor = nv04_fifo_dtor,
.init = nv40_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

View File

@ -0,0 +1,517 @@
/*
* 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/client.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <core/class.h>
#include <subdev/timer.h>
#include <subdev/bar.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include "nv04.h"
#include "nv50.h"
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static void
nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv)
{
struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_gpuobj *cur;
int i, p;
cur = priv->playlist[priv->cur_playlist];
priv->cur_playlist = !priv->cur_playlist;
for (i = priv->base.min, p = 0; i < priv->base.max; i++) {
if (nv_rd32(priv, 0x002600 + (i * 4)) & 0x80000000)
nv_wo32(cur, p++ * 4, i);
}
bar->flush(bar);
nv_wr32(priv, 0x0032f4, cur->addr >> 12);
nv_wr32(priv, 0x0032ec, p);
nv_wr32(priv, 0x002500, 0x00000101);
}
void
nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
{
mutex_lock(&nv_subdev(priv)->mutex);
nv50_fifo_playlist_update_locked(priv);
mutex_unlock(&nv_subdev(priv)->mutex);
}
static int
nv50_fifo_context_attach(struct nouveau_object *parent,
struct nouveau_object *object)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent->parent;
struct nouveau_gpuobj *ectx = (void *)object;
u64 limit = ectx->addr + ectx->size - 1;
u64 start = ectx->addr;
u32 addr;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0000; break;
case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
default:
return -EINVAL;
}
nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
nv_wo32(base->eng, addr + 0x00, 0x00190000);
nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
nv_wo32(base->eng, addr + 0x0c, upper_32_bits(limit) << 24 |
upper_32_bits(start));
nv_wo32(base->eng, addr + 0x10, 0x00000000);
nv_wo32(base->eng, addr + 0x14, 0x00000000);
bar->flush(bar);
return 0;
}
static int
nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
struct nouveau_object *object)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_priv *priv = (void *)parent->engine;
struct nv50_fifo_base *base = (void *)parent->parent;
struct nv50_fifo_chan *chan = (void *)parent;
u32 addr, me;
int ret = 0;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0000; break;
case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
default:
return -EINVAL;
}
/* HW bug workaround:
*
* PFIFO will hang forever if the connected engines don't report
* that they've processed the context switch request.
*
* In order for the kickoff to work, we need to ensure all the
* connected engines are in a state where they can answer.
*
* Newer chipsets don't seem to suffer from this issue, and well,
* there's also a "ignore these engines" bitmask reg we can use
* if we hit the issue there..
*/
me = nv_mask(priv, 0x00b860, 0x00000001, 0x00000001);
/* do the kickoff... */
nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
if (!nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff)) {
nv_error(priv, "channel %d [%s] unload timeout\n",
chan->base.chid, nouveau_client_name(chan));
if (suspend)
ret = -EBUSY;
}
nv_wr32(priv, 0x00b860, me);
if (ret == 0) {
nv_wo32(base->eng, addr + 0x00, 0x00000000);
nv_wo32(base->eng, addr + 0x04, 0x00000000);
nv_wo32(base->eng, addr + 0x08, 0x00000000);
nv_wo32(base->eng, addr + 0x0c, 0x00000000);
nv_wo32(base->eng, addr + 0x10, 0x00000000);
nv_wo32(base->eng, addr + 0x14, 0x00000000);
bar->flush(bar);
}
return ret;
}
static int
nv50_fifo_object_attach(struct nouveau_object *parent,
struct nouveau_object *object, u32 handle)
{
struct nv50_fifo_chan *chan = (void *)parent;
u32 context;
if (nv_iclass(object, NV_GPUOBJ_CLASS))
context = nv_gpuobj(object)->node->offset >> 4;
else
context = 0x00000004; /* just non-zero */
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_DMAOBJ:
case NVDEV_ENGINE_SW : context |= 0x00000000; break;
case NVDEV_ENGINE_GR : context |= 0x00100000; break;
case NVDEV_ENGINE_MPEG : context |= 0x00200000; break;
default:
return -EINVAL;
}
return nouveau_ramht_insert(chan->ramht, 0, handle, context);
}
void
nv50_fifo_object_detach(struct nouveau_object *parent, int cookie)
{
struct nv50_fifo_chan *chan = (void *)parent;
nouveau_ramht_remove(chan->ramht, cookie);
}
static int
nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_MPEG), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->context_attach = nv50_fifo_context_attach;
nv_parent(chan)->context_detach = nv50_fifo_context_detach;
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
&chan->ramht);
if (ret)
return ret;
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x3c, 0x003f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
nv_wo32(base->ramfc, 0x4c, 0xffffffff);
nv_wo32(base->ramfc, 0x60, 0x7fffffff);
nv_wo32(base->ramfc, 0x78, 0x00000000);
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->base.node->offset >> 4));
bar->flush(bar);
return 0;
}
static int
nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_channel_ind_class *args = data;
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
u64 ioffset, ilength;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_MPEG), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->context_attach = nv50_fifo_context_attach;
nv_parent(chan)->context_detach = nv50_fifo_context_detach;
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
&chan->ramht);
if (ret)
return ret;
ioffset = args->ioffset;
ilength = order_base_2(args->ilength / 8);
nv_wo32(base->ramfc, 0x3c, 0x403f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
nv_wo32(base->ramfc, 0x50, lower_32_bits(ioffset));
nv_wo32(base->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
nv_wo32(base->ramfc, 0x60, 0x7fffffff);
nv_wo32(base->ramfc, 0x78, 0x00000000);
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->base.node->offset >> 4));
bar->flush(bar);
return 0;
}
void
nv50_fifo_chan_dtor(struct nouveau_object *object)
{
struct nv50_fifo_chan *chan = (void *)object;
nouveau_ramht_ref(NULL, &chan->ramht);
nouveau_fifo_channel_destroy(&chan->base);
}
static int
nv50_fifo_chan_init(struct nouveau_object *object)
{
struct nv50_fifo_priv *priv = (void *)object->engine;
struct nv50_fifo_base *base = (void *)object->parent;
struct nv50_fifo_chan *chan = (void *)object;
struct nouveau_gpuobj *ramfc = base->ramfc;
u32 chid = chan->base.chid;
int ret;
ret = nouveau_fifo_channel_init(&chan->base);
if (ret)
return ret;
nv_wr32(priv, 0x002600 + (chid * 4), 0x80000000 | ramfc->addr >> 12);
nv50_fifo_playlist_update(priv);
return 0;
}
int
nv50_fifo_chan_fini(struct nouveau_object *object, bool suspend)
{
struct nv50_fifo_priv *priv = (void *)object->engine;
struct nv50_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
/* remove channel from playlist, fifo will unload context */
nv_mask(priv, 0x002600 + (chid * 4), 0x80000000, 0x00000000);
nv50_fifo_playlist_update(priv);
nv_wr32(priv, 0x002600 + (chid * 4), 0x00000000);
return nouveau_fifo_channel_fini(&chan->base, suspend);
}
static struct nouveau_ofuncs
nv50_fifo_ofuncs_dma = {
.ctor = nv50_fifo_chan_ctor_dma,
.dtor = nv50_fifo_chan_dtor,
.init = nv50_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_ofuncs
nv50_fifo_ofuncs_ind = {
.ctor = nv50_fifo_chan_ctor_ind,
.dtor = nv50_fifo_chan_dtor,
.init = nv50_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nv50_fifo_sclass[] = {
{ NV50_CHANNEL_DMA_CLASS, &nv50_fifo_ofuncs_dma },
{ NV50_CHANNEL_IND_CLASS, &nv50_fifo_ofuncs_ind },
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
static int
nv50_fifo_context_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_fifo_base *base;
int ret;
ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
0x1000, NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200,
0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1200, 0,
NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0, 0,
&base->pgd);
if (ret)
return ret;
ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
return 0;
}
void
nv50_fifo_context_dtor(struct nouveau_object *object)
{
struct nv50_fifo_base *base = (void *)object;
nouveau_vm_ref(NULL, &base->vm, base->pgd);
nouveau_gpuobj_ref(NULL, &base->pgd);
nouveau_gpuobj_ref(NULL, &base->eng);
nouveau_gpuobj_ref(NULL, &base->ramfc);
nouveau_gpuobj_ref(NULL, &base->cache);
nouveau_fifo_context_destroy(&base->base);
}
static struct nouveau_oclass
nv50_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x50),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_fifo_context_ctor,
.dtor = nv50_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static int
nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
&priv->playlist[0]);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
&priv->playlist[1]);
if (ret)
return ret;
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv50_fifo_cclass;
nv_engine(priv)->sclass = nv50_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
return 0;
}
void
nv50_fifo_dtor(struct nouveau_object *object)
{
struct nv50_fifo_priv *priv = (void *)object;
nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
nouveau_fifo_destroy(&priv->base);
}
int
nv50_fifo_init(struct nouveau_object *object)
{
struct nv50_fifo_priv *priv = (void *)object;
int ret, i;
ret = nouveau_fifo_init(&priv->base);
if (ret)
return ret;
nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
nv_wr32(priv, 0x00250c, 0x6f3cfc34);
nv_wr32(priv, 0x002044, 0x01003fff);
nv_wr32(priv, 0x002100, 0xffffffff);
nv_wr32(priv, 0x002140, 0xbfffffff);
for (i = 0; i < 128; i++)
nv_wr32(priv, 0x002600 + (i * 4), 0x00000000);
nv50_fifo_playlist_update_locked(priv);
nv_wr32(priv, 0x003200, 0x00000001);
nv_wr32(priv, 0x003250, 0x00000001);
nv_wr32(priv, 0x002500, 0x00000001);
return 0;
}
struct nouveau_oclass *
nv50_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0x50),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv50_fifo_ctor,
.dtor = nv50_fifo_dtor,
.init = nv50_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

View File

@ -0,0 +1,36 @@
#ifndef __NV50_FIFO_H__
#define __NV50_FIFO_H__
struct nv50_fifo_priv {
struct nouveau_fifo base;
struct nouveau_gpuobj *playlist[2];
int cur_playlist;
};
struct nv50_fifo_base {
struct nouveau_fifo_base base;
struct nouveau_gpuobj *ramfc;
struct nouveau_gpuobj *cache;
struct nouveau_gpuobj *eng;
struct nouveau_gpuobj *pgd;
struct nouveau_vm *vm;
};
struct nv50_fifo_chan {
struct nouveau_fifo_chan base;
u32 subc[8];
struct nouveau_ramht *ramht;
};
void nv50_fifo_playlist_update(struct nv50_fifo_priv *);
void nv50_fifo_object_detach(struct nouveau_object *, int);
void nv50_fifo_chan_dtor(struct nouveau_object *);
int nv50_fifo_chan_fini(struct nouveau_object *, bool);
void nv50_fifo_context_dtor(struct nouveau_object *);
void nv50_fifo_dtor(struct nouveau_object *);
int nv50_fifo_init(struct nouveau_object *);
#endif

View File

@ -0,0 +1,450 @@
/*
* 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/os.h>
#include <core/client.h>
#include <core/engctx.h>
#include <core/ramht.h>
#include <core/event.h>
#include <core/class.h>
#include <subdev/timer.h>
#include <subdev/bar.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
#include "nv04.h"
#include "nv50.h"
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static int
nv84_fifo_context_attach(struct nouveau_object *parent,
struct nouveau_object *object)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent->parent;
struct nouveau_gpuobj *ectx = (void *)object;
u64 limit = ectx->addr + ectx->size - 1;
u64 start = ectx->addr;
u32 addr;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0020; break;
case NVDEV_ENGINE_VP : addr = 0x0040; break;
case NVDEV_ENGINE_PPP :
case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
case NVDEV_ENGINE_BSP : addr = 0x0080; break;
case NVDEV_ENGINE_CRYPT: addr = 0x00a0; break;
case NVDEV_ENGINE_COPY0: addr = 0x00c0; break;
default:
return -EINVAL;
}
nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
nv_wo32(base->eng, addr + 0x00, 0x00190000);
nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
nv_wo32(base->eng, addr + 0x0c, upper_32_bits(limit) << 24 |
upper_32_bits(start));
nv_wo32(base->eng, addr + 0x10, 0x00000000);
nv_wo32(base->eng, addr + 0x14, 0x00000000);
bar->flush(bar);
return 0;
}
static int
nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend,
struct nouveau_object *object)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_priv *priv = (void *)parent->engine;
struct nv50_fifo_base *base = (void *)parent->parent;
struct nv50_fifo_chan *chan = (void *)parent;
u32 addr, save, engn;
bool done;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : engn = 0; addr = 0x0020; break;
case NVDEV_ENGINE_VP : engn = 3; addr = 0x0040; break;
case NVDEV_ENGINE_PPP :
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_COPY0: engn = 2; addr = 0x00c0; break;
default:
return -EINVAL;
}
save = nv_mask(priv, 0x002520, 0x0000003f, 1 << engn);
nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
done = nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff);
nv_wr32(priv, 0x002520, save);
if (!done) {
nv_error(priv, "channel %d [%s] unload timeout\n",
chan->base.chid, nouveau_client_name(chan));
if (suspend)
return -EBUSY;
}
nv_wo32(base->eng, addr + 0x00, 0x00000000);
nv_wo32(base->eng, addr + 0x04, 0x00000000);
nv_wo32(base->eng, addr + 0x08, 0x00000000);
nv_wo32(base->eng, addr + 0x0c, 0x00000000);
nv_wo32(base->eng, addr + 0x10, 0x00000000);
nv_wo32(base->eng, addr + 0x14, 0x00000000);
bar->flush(bar);
return 0;
}
static int
nv84_fifo_object_attach(struct nouveau_object *parent,
struct nouveau_object *object, u32 handle)
{
struct nv50_fifo_chan *chan = (void *)parent;
u32 context;
if (nv_iclass(object, NV_GPUOBJ_CLASS))
context = nv_gpuobj(object)->node->offset >> 4;
else
context = 0x00000004; /* just non-zero */
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_DMAOBJ:
case NVDEV_ENGINE_SW : context |= 0x00000000; break;
case NVDEV_ENGINE_GR : context |= 0x00100000; break;
case NVDEV_ENGINE_MPEG :
case NVDEV_ENGINE_PPP : context |= 0x00200000; break;
case NVDEV_ENGINE_ME :
case NVDEV_ENGINE_COPY0 : context |= 0x00300000; break;
case NVDEV_ENGINE_VP : context |= 0x00400000; break;
case NVDEV_ENGINE_CRYPT :
case NVDEV_ENGINE_VIC : context |= 0x00500000; break;
case NVDEV_ENGINE_BSP : context |= 0x00600000; break;
default:
return -EINVAL;
}
return nouveau_ramht_insert(chan->ramht, 0, handle, context);
}
static int
nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
struct nv03_channel_dma_class *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_MPEG) |
(1ULL << NVDEV_ENGINE_ME) |
(1ULL << NVDEV_ENGINE_VP) |
(1ULL << NVDEV_ENGINE_CRYPT) |
(1ULL << NVDEV_ENGINE_BSP) |
(1ULL << NVDEV_ENGINE_PPP) |
(1ULL << NVDEV_ENGINE_COPY0) |
(1ULL << NVDEV_ENGINE_VIC), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
&chan->ramht);
if (ret)
return ret;
nv_parent(chan)->context_attach = nv84_fifo_context_attach;
nv_parent(chan)->context_detach = nv84_fifo_context_detach;
nv_parent(chan)->object_attach = nv84_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
nv_wo32(base->ramfc, 0x3c, 0x003f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
nv_wo32(base->ramfc, 0x4c, 0xffffffff);
nv_wo32(base->ramfc, 0x60, 0x7fffffff);
nv_wo32(base->ramfc, 0x78, 0x00000000);
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->base.node->offset >> 4));
nv_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
nv_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
bar->flush(bar);
return 0;
}
static int
nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan;
struct nv50_channel_ind_class *args = data;
u64 ioffset, ilength;
int ret;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
0x2000, args->pushbuf,
(1ULL << NVDEV_ENGINE_DMAOBJ) |
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_MPEG) |
(1ULL << NVDEV_ENGINE_ME) |
(1ULL << NVDEV_ENGINE_VP) |
(1ULL << NVDEV_ENGINE_CRYPT) |
(1ULL << NVDEV_ENGINE_BSP) |
(1ULL << NVDEV_ENGINE_PPP) |
(1ULL << NVDEV_ENGINE_COPY0) |
(1ULL << NVDEV_ENGINE_VIC), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
&chan->ramht);
if (ret)
return ret;
nv_parent(chan)->context_attach = nv84_fifo_context_attach;
nv_parent(chan)->context_detach = nv84_fifo_context_detach;
nv_parent(chan)->object_attach = nv84_fifo_object_attach;
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
ioffset = args->ioffset;
ilength = order_base_2(args->ilength / 8);
nv_wo32(base->ramfc, 0x3c, 0x403f6078);
nv_wo32(base->ramfc, 0x44, 0x01003fff);
nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
nv_wo32(base->ramfc, 0x50, lower_32_bits(ioffset));
nv_wo32(base->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
nv_wo32(base->ramfc, 0x60, 0x7fffffff);
nv_wo32(base->ramfc, 0x78, 0x00000000);
nv_wo32(base->ramfc, 0x7c, 0x30000001);
nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->base.node->offset >> 4));
nv_wo32(base->ramfc, 0x88, base->cache->addr >> 10);
nv_wo32(base->ramfc, 0x98, nv_gpuobj(base)->addr >> 12);
bar->flush(bar);
return 0;
}
static int
nv84_fifo_chan_init(struct nouveau_object *object)
{
struct nv50_fifo_priv *priv = (void *)object->engine;
struct nv50_fifo_base *base = (void *)object->parent;
struct nv50_fifo_chan *chan = (void *)object;
struct nouveau_gpuobj *ramfc = base->ramfc;
u32 chid = chan->base.chid;
int ret;
ret = nouveau_fifo_channel_init(&chan->base);
if (ret)
return ret;
nv_wr32(priv, 0x002600 + (chid * 4), 0x80000000 | ramfc->addr >> 8);
nv50_fifo_playlist_update(priv);
return 0;
}
static struct nouveau_ofuncs
nv84_fifo_ofuncs_dma = {
.ctor = nv84_fifo_chan_ctor_dma,
.dtor = nv50_fifo_chan_dtor,
.init = nv84_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_ofuncs
nv84_fifo_ofuncs_ind = {
.ctor = nv84_fifo_chan_ctor_ind,
.dtor = nv50_fifo_chan_dtor,
.init = nv84_fifo_chan_init,
.fini = nv50_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nv84_fifo_sclass[] = {
{ NV84_CHANNEL_DMA_CLASS, &nv84_fifo_ofuncs_dma },
{ NV84_CHANNEL_IND_CLASS, &nv84_fifo_ofuncs_ind },
{}
};
/*******************************************************************************
* FIFO context - basically just the instmem reserved for the channel
******************************************************************************/
static int
nv84_fifo_context_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_fifo_base *base;
int ret;
ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
0x1000, NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200, 0,
NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0,
0, &base->pgd);
if (ret)
return ret;
ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1000,
0x400, NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0100,
0x100, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
if (ret)
return ret;
return 0;
}
static struct nouveau_oclass
nv84_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_fifo_context_ctor,
.dtor = nv50_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static void
nv84_fifo_uevent_enable(struct nouveau_event *event, int index)
{
struct nv84_fifo_priv *priv = event->priv;
nv_mask(priv, 0x002140, 0x40000000, 0x40000000);
}
static void
nv84_fifo_uevent_disable(struct nouveau_event *event, int index)
{
struct nv84_fifo_priv *priv = event->priv;
nv_mask(priv, 0x002140, 0x40000000, 0x00000000);
}
static int
nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nv50_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
&priv->playlist[0]);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
&priv->playlist[1]);
if (ret)
return ret;
priv->base.uevent->enable = nv84_fifo_uevent_enable;
priv->base.uevent->disable = nv84_fifo_uevent_disable;
priv->base.uevent->priv = priv;
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nv04_fifo_intr;
nv_engine(priv)->cclass = &nv84_fifo_cclass;
nv_engine(priv)->sclass = nv84_fifo_sclass;
priv->base.pause = nv04_fifo_pause;
priv->base.start = nv04_fifo_start;
return 0;
}
struct nouveau_oclass *
nv84_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0x84),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nv84_fifo_ctor,
.dtor = nv50_fifo_dtor,
.init = nv50_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

View File

@ -0,0 +1,955 @@
/*
* 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/client.h>
#include <core/handle.h>
#include <core/namedb.h>
#include <core/gpuobj.h>
#include <core/engctx.h>
#include <core/event.h>
#include <core/class.h>
#include <core/enum.h>
#include <subdev/timer.h>
#include <subdev/bar.h>
#include <subdev/fb.h>
#include <subdev/vm.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
struct nvc0_fifo_priv {
struct nouveau_fifo base;
struct work_struct fault;
u64 mask;
struct {
struct nouveau_gpuobj *mem[2];
int active;
wait_queue_head_t wait;
} runlist;
struct {
struct nouveau_gpuobj *mem;
struct nouveau_vma bar;
} user;
int spoon_nr;
};
struct nvc0_fifo_base {
struct nouveau_fifo_base base;
struct nouveau_gpuobj *pgd;
struct nouveau_vm *vm;
};
struct nvc0_fifo_chan {
struct nouveau_fifo_chan base;
enum {
STOPPED,
RUNNING,
KILLED
} state;
};
/*******************************************************************************
* FIFO channel objects
******************************************************************************/
static void
nvc0_fifo_runlist_update(struct nvc0_fifo_priv *priv)
{
struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_gpuobj *cur;
int i, p;
mutex_lock(&nv_subdev(priv)->mutex);
cur = priv->runlist.mem[priv->runlist.active];
priv->runlist.active = !priv->runlist.active;
for (i = 0, p = 0; i < 128; i++) {
struct nvc0_fifo_chan *chan = (void *)priv->base.channel[i];
if (chan && chan->state == RUNNING) {
nv_wo32(cur, p + 0, i);
nv_wo32(cur, p + 4, 0x00000004);
p += 8;
}
}
bar->flush(bar);
nv_wr32(priv, 0x002270, cur->addr >> 12);
nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3));
if (wait_event_timeout(priv->runlist.wait,
!(nv_rd32(priv, 0x00227c) & 0x00100000),
msecs_to_jiffies(2000)) == 0)
nv_error(priv, "runlist update timeout\n");
mutex_unlock(&nv_subdev(priv)->mutex);
}
static int
nvc0_fifo_context_attach(struct nouveau_object *parent,
struct nouveau_object *object)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nvc0_fifo_base *base = (void *)parent->parent;
struct nouveau_engctx *ectx = (void *)object;
u32 addr;
int ret;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0210; break;
case NVDEV_ENGINE_COPY0: addr = 0x0230; break;
case NVDEV_ENGINE_COPY1: addr = 0x0240; break;
case NVDEV_ENGINE_BSP : addr = 0x0270; break;
case NVDEV_ENGINE_VP : addr = 0x0250; break;
case NVDEV_ENGINE_PPP : addr = 0x0260; break;
default:
return -EINVAL;
}
if (!ectx->vma.node) {
ret = nouveau_gpuobj_map_vm(nv_gpuobj(ectx), base->vm,
NV_MEM_ACCESS_RW, &ectx->vma);
if (ret)
return ret;
nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
}
nv_wo32(base, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4);
nv_wo32(base, addr + 0x04, upper_32_bits(ectx->vma.offset));
bar->flush(bar);
return 0;
}
static int
nvc0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
struct nouveau_object *object)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nvc0_fifo_priv *priv = (void *)parent->engine;
struct nvc0_fifo_base *base = (void *)parent->parent;
struct nvc0_fifo_chan *chan = (void *)parent;
u32 addr;
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
case NVDEV_ENGINE_GR : addr = 0x0210; break;
case NVDEV_ENGINE_COPY0: addr = 0x0230; break;
case NVDEV_ENGINE_COPY1: addr = 0x0240; break;
case NVDEV_ENGINE_BSP : addr = 0x0270; break;
case NVDEV_ENGINE_VP : addr = 0x0250; break;
case NVDEV_ENGINE_PPP : addr = 0x0260; break;
default:
return -EINVAL;
}
nv_wr32(priv, 0x002634, chan->base.chid);
if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) {
nv_error(priv, "channel %d [%s] kick timeout\n",
chan->base.chid, nouveau_client_name(chan));
if (suspend)
return -EBUSY;
}
nv_wo32(base, addr + 0x00, 0x00000000);
nv_wo32(base, addr + 0x04, 0x00000000);
bar->flush(bar);
return 0;
}
static int
nvc0_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nouveau_bar *bar = nouveau_bar(parent);
struct nvc0_fifo_priv *priv = (void *)engine;
struct nvc0_fifo_base *base = (void *)parent;
struct nvc0_fifo_chan *chan;
struct nv50_channel_ind_class *args = data;
u64 usermem, ioffset, ilength;
int ret, i;
if (size < sizeof(*args))
return -EINVAL;
ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
priv->user.bar.offset, 0x1000,
args->pushbuf,
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_COPY0) |
(1ULL << NVDEV_ENGINE_COPY1) |
(1ULL << NVDEV_ENGINE_BSP) |
(1ULL << NVDEV_ENGINE_VP) |
(1ULL << NVDEV_ENGINE_PPP), &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->context_attach = nvc0_fifo_context_attach;
nv_parent(chan)->context_detach = nvc0_fifo_context_detach;
usermem = chan->base.chid * 0x1000;
ioffset = args->ioffset;
ilength = order_base_2(args->ilength / 8);
for (i = 0; i < 0x1000; i += 4)
nv_wo32(priv->user.mem, usermem + i, 0x00000000);
nv_wo32(base, 0x08, lower_32_bits(priv->user.mem->addr + usermem));
nv_wo32(base, 0x0c, upper_32_bits(priv->user.mem->addr + usermem));
nv_wo32(base, 0x10, 0x0000face);
nv_wo32(base, 0x30, 0xfffff902);
nv_wo32(base, 0x48, lower_32_bits(ioffset));
nv_wo32(base, 0x4c, upper_32_bits(ioffset) | (ilength << 16));
nv_wo32(base, 0x54, 0x00000002);
nv_wo32(base, 0x84, 0x20400000);
nv_wo32(base, 0x94, 0x30000001);
nv_wo32(base, 0x9c, 0x00000100);
nv_wo32(base, 0xa4, 0x1f1f1f1f);
nv_wo32(base, 0xa8, 0x1f1f1f1f);
nv_wo32(base, 0xac, 0x0000001f);
nv_wo32(base, 0xb8, 0xf8000000);
nv_wo32(base, 0xf8, 0x10003080); /* 0x002310 */
nv_wo32(base, 0xfc, 0x10000010); /* 0x002350 */
bar->flush(bar);
return 0;
}
static int
nvc0_fifo_chan_init(struct nouveau_object *object)
{
struct nouveau_gpuobj *base = nv_gpuobj(object->parent);
struct nvc0_fifo_priv *priv = (void *)object->engine;
struct nvc0_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
int ret;
ret = nouveau_fifo_channel_init(&chan->base);
if (ret)
return ret;
nv_wr32(priv, 0x003000 + (chid * 8), 0xc0000000 | base->addr >> 12);
if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) {
nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001);
nvc0_fifo_runlist_update(priv);
}
return 0;
}
static void nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv);
static int
nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
{
struct nvc0_fifo_priv *priv = (void *)object->engine;
struct nvc0_fifo_chan *chan = (void *)object;
u32 chid = chan->base.chid;
if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) {
nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000);
nvc0_fifo_runlist_update(priv);
}
nvc0_fifo_intr_engine(priv);
nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000);
return nouveau_fifo_channel_fini(&chan->base, suspend);
}
static struct nouveau_ofuncs
nvc0_fifo_ofuncs = {
.ctor = nvc0_fifo_chan_ctor,
.dtor = _nouveau_fifo_channel_dtor,
.init = nvc0_fifo_chan_init,
.fini = nvc0_fifo_chan_fini,
.rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32,
};
static struct nouveau_oclass
nvc0_fifo_sclass[] = {
{ NVC0_CHANNEL_IND_CLASS, &nvc0_fifo_ofuncs },
{}
};
/*******************************************************************************
* FIFO context - instmem heap and vm setup
******************************************************************************/
static int
nvc0_fifo_context_ctor(struct nouveau_object *parent,
struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvc0_fifo_base *base;
int ret;
ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x1000,
0x1000, NVOBJ_FLAG_ZERO_ALLOC |
NVOBJ_FLAG_HEAP, &base);
*pobject = nv_object(base);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
&base->pgd);
if (ret)
return ret;
nv_wo32(base, 0x0200, lower_32_bits(base->pgd->addr));
nv_wo32(base, 0x0204, upper_32_bits(base->pgd->addr));
nv_wo32(base, 0x0208, 0xffffffff);
nv_wo32(base, 0x020c, 0x000000ff);
ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
if (ret)
return ret;
return 0;
}
static void
nvc0_fifo_context_dtor(struct nouveau_object *object)
{
struct nvc0_fifo_base *base = (void *)object;
nouveau_vm_ref(NULL, &base->vm, base->pgd);
nouveau_gpuobj_ref(NULL, &base->pgd);
nouveau_fifo_context_destroy(&base->base);
}
static struct nouveau_oclass
nvc0_fifo_cclass = {
.handle = NV_ENGCTX(FIFO, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_fifo_context_ctor,
.dtor = nvc0_fifo_context_dtor,
.init = _nouveau_fifo_context_init,
.fini = _nouveau_fifo_context_fini,
.rd32 = _nouveau_fifo_context_rd32,
.wr32 = _nouveau_fifo_context_wr32,
},
};
/*******************************************************************************
* PFIFO engine
******************************************************************************/
static inline int
nvc0_fifo_engidx(struct nvc0_fifo_priv *priv, u32 engn)
{
switch (engn) {
case NVDEV_ENGINE_GR : engn = 0; break;
case NVDEV_ENGINE_BSP : engn = 1; break;
case NVDEV_ENGINE_PPP : engn = 2; break;
case NVDEV_ENGINE_VP : engn = 3; break;
case NVDEV_ENGINE_COPY0: engn = 4; break;
case NVDEV_ENGINE_COPY1: engn = 5; break;
default:
return -1;
}
return engn;
}
static inline struct nouveau_engine *
nvc0_fifo_engine(struct nvc0_fifo_priv *priv, u32 engn)
{
switch (engn) {
case 0: engn = NVDEV_ENGINE_GR; break;
case 1: engn = NVDEV_ENGINE_BSP; break;
case 2: engn = NVDEV_ENGINE_PPP; break;
case 3: engn = NVDEV_ENGINE_VP; break;
case 4: engn = NVDEV_ENGINE_COPY0; break;
case 5: engn = NVDEV_ENGINE_COPY1; break;
default:
return NULL;
}
return nouveau_engine(priv, engn);
}
static void
nvc0_fifo_recover_work(struct work_struct *work)
{
struct nvc0_fifo_priv *priv = container_of(work, typeof(*priv), fault);
struct nouveau_object *engine;
unsigned long flags;
u32 engn, engm = 0;
u64 mask, todo;
spin_lock_irqsave(&priv->base.lock, flags);
mask = priv->mask;
priv->mask = 0ULL;
spin_unlock_irqrestore(&priv->base.lock, flags);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
engm |= 1 << nvc0_fifo_engidx(priv, engn);
nv_mask(priv, 0x002630, engm, engm);
for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
if ((engine = (void *)nouveau_engine(priv, engn))) {
nv_ofuncs(engine)->fini(engine, false);
WARN_ON(nv_ofuncs(engine)->init(engine));
}
}
nvc0_fifo_runlist_update(priv);
nv_wr32(priv, 0x00262c, engm);
nv_mask(priv, 0x002630, engm, 0x00000000);
}
static void
nvc0_fifo_recover(struct nvc0_fifo_priv *priv, struct nouveau_engine *engine,
struct nvc0_fifo_chan *chan)
{
struct nouveau_object *engobj = nv_object(engine);
u32 chid = chan->base.chid;
unsigned long flags;
nv_error(priv, "%s engine fault on channel %d, recovering...\n",
nv_subdev(engine)->name, chid);
nv_mask(priv, 0x003004 + (chid * 0x08), 0x00000001, 0x00000000);
chan->state = KILLED;
spin_lock_irqsave(&priv->base.lock, flags);
priv->mask |= 1ULL << nv_engidx(engobj);
spin_unlock_irqrestore(&priv->base.lock, flags);
schedule_work(&priv->fault);
}
static int
nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
{
struct nvc0_fifo_chan *chan = NULL;
struct nouveau_handle *bind;
unsigned long flags;
int ret = -EINVAL;
spin_lock_irqsave(&priv->base.lock, flags);
if (likely(chid >= priv->base.min && chid <= priv->base.max))
chan = (void *)priv->base.channel[chid];
if (unlikely(!chan))
goto out;
bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
if (likely(bind)) {
if (!mthd || !nv_call(bind->object, mthd, data))
ret = 0;
nouveau_namedb_put(bind);
}
out:
spin_unlock_irqrestore(&priv->base.lock, flags);
return ret;
}
static const struct nouveau_enum
nvc0_fifo_sched_reason[] = {
{ 0x0a, "CTXSW_TIMEOUT" },
{}
};
static void
nvc0_fifo_intr_sched_ctxsw(struct nvc0_fifo_priv *priv)
{
struct nouveau_engine *engine;
struct nvc0_fifo_chan *chan;
u32 engn;
for (engn = 0; engn < 6; engn++) {
u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04));
u32 busy = (stat & 0x80000000);
u32 save = (stat & 0x00100000); /* maybe? */
u32 unk0 = (stat & 0x00040000);
u32 unk1 = (stat & 0x00001000);
u32 chid = (stat & 0x0000007f);
(void)save;
if (busy && unk0 && unk1) {
if (!(chan = (void *)priv->base.channel[chid]))
continue;
if (!(engine = nvc0_fifo_engine(priv, engn)))
continue;
nvc0_fifo_recover(priv, engine, chan);
}
}
}
static void
nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv)
{
u32 intr = nv_rd32(priv, 0x00254c);
u32 code = intr & 0x000000ff;
const struct nouveau_enum *en;
char enunk[6] = "";
en = nouveau_enum_find(nvc0_fifo_sched_reason, code);
if (!en)
snprintf(enunk, sizeof(enunk), "UNK%02x", code);
nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk);
switch (code) {
case 0x0a:
nvc0_fifo_intr_sched_ctxsw(priv);
break;
default:
break;
}
}
static const struct nouveau_enum
nvc0_fifo_fault_engine[] = {
{ 0x00, "PGRAPH", NULL, NVDEV_ENGINE_GR },
{ 0x03, "PEEPHOLE", NULL, NVDEV_ENGINE_IFB },
{ 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR },
{ 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM },
{ 0x07, "PFIFO", NULL, NVDEV_ENGINE_FIFO },
{ 0x10, "PBSP", NULL, NVDEV_ENGINE_BSP },
{ 0x11, "PPPP", NULL, NVDEV_ENGINE_PPP },
{ 0x13, "PCOUNTER" },
{ 0x14, "PVP", NULL, NVDEV_ENGINE_VP },
{ 0x15, "PCOPY0", NULL, NVDEV_ENGINE_COPY0 },
{ 0x16, "PCOPY1", NULL, NVDEV_ENGINE_COPY1 },
{ 0x17, "PDAEMON" },
{}
};
static const struct nouveau_enum
nvc0_fifo_fault_reason[] = {
{ 0x00, "PT_NOT_PRESENT" },
{ 0x01, "PT_TOO_SHORT" },
{ 0x02, "PAGE_NOT_PRESENT" },
{ 0x03, "VM_LIMIT_EXCEEDED" },
{ 0x04, "NO_CHANNEL" },
{ 0x05, "PAGE_SYSTEM_ONLY" },
{ 0x06, "PAGE_READ_ONLY" },
{ 0x0a, "COMPRESSED_SYSRAM" },
{ 0x0c, "INVALID_STORAGE_TYPE" },
{}
};
static const struct nouveau_enum
nvc0_fifo_fault_hubclient[] = {
{ 0x01, "PCOPY0" },
{ 0x02, "PCOPY1" },
{ 0x04, "DISPATCH" },
{ 0x05, "CTXCTL" },
{ 0x06, "PFIFO" },
{ 0x07, "BAR_READ" },
{ 0x08, "BAR_WRITE" },
{ 0x0b, "PVP" },
{ 0x0c, "PPPP" },
{ 0x0d, "PBSP" },
{ 0x11, "PCOUNTER" },
{ 0x12, "PDAEMON" },
{ 0x14, "CCACHE" },
{ 0x15, "CCACHE_POST" },
{}
};
static const struct nouveau_enum
nvc0_fifo_fault_gpcclient[] = {
{ 0x01, "TEX" },
{ 0x0c, "ESETUP" },
{ 0x0e, "CTXCTL" },
{ 0x0f, "PROP" },
{}
};
static void
nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
{
u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10));
u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10));
u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10));
u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10));
u32 gpc = (stat & 0x1f000000) >> 24;
u32 client = (stat & 0x00001f00) >> 8;
u32 write = (stat & 0x00000080);
u32 hub = (stat & 0x00000040);
u32 reason = (stat & 0x0000000f);
struct nouveau_object *engctx = NULL, *object;
struct nouveau_engine *engine = NULL;
const struct nouveau_enum *er, *eu, *ec;
char erunk[6] = "";
char euunk[6] = "";
char ecunk[6] = "";
char gpcid[3] = "";
er = nouveau_enum_find(nvc0_fifo_fault_reason, reason);
if (!er)
snprintf(erunk, sizeof(erunk), "UNK%02X", reason);
eu = nouveau_enum_find(nvc0_fifo_fault_engine, unit);
if (eu) {
switch (eu->data2) {
case NVDEV_SUBDEV_BAR:
nv_mask(priv, 0x001704, 0x00000000, 0x00000000);
break;
case NVDEV_SUBDEV_INSTMEM:
nv_mask(priv, 0x001714, 0x00000000, 0x00000000);
break;
case NVDEV_ENGINE_IFB:
nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
break;
default:
engine = nouveau_engine(priv, eu->data2);
if (engine)
engctx = nouveau_engctx_get(engine, inst);
break;
}
} else {
snprintf(euunk, sizeof(euunk), "UNK%02x", unit);
}
if (hub) {
ec = nouveau_enum_find(nvc0_fifo_fault_hubclient, client);
} else {
ec = nouveau_enum_find(nvc0_fifo_fault_gpcclient, client);
snprintf(gpcid, sizeof(gpcid), "%d", gpc);
}
if (!ec)
snprintf(ecunk, sizeof(ecunk), "UNK%02x", client);
nv_error(priv, "%s fault at 0x%010llx [%s] from %s/%s%s%s%s on "
"channel 0x%010llx [%s]\n", write ? "write" : "read",
(u64)vahi << 32 | valo, er ? er->name : erunk,
eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/",
ec ? ec->name : ecunk, (u64)inst << 12,
nouveau_client_name(engctx));
object = engctx;
while (object) {
switch (nv_mclass(object)) {
case NVC0_CHANNEL_IND_CLASS:
nvc0_fifo_recover(priv, engine, (void *)object);
break;
}
object = object->parent;
}
nouveau_engctx_put(engctx);
}
static const struct nouveau_bitfield
nvc0_fifo_pbdma_intr[] = {
/* { 0x00008000, "" } seen with null ib push */
{ 0x00200000, "ILLEGAL_MTHD" },
{ 0x00800000, "EMPTY_SUBC" },
{}
};
static void
nvc0_fifo_intr_pbdma(struct nvc0_fifo_priv *priv, int unit)
{
u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000));
u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000));
u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0x7f;
u32 subc = (addr & 0x00070000) >> 16;
u32 mthd = (addr & 0x00003ffc);
u32 show = stat;
if (stat & 0x00800000) {
if (!nvc0_fifo_swmthd(priv, chid, mthd, data))
show &= ~0x00800000;
}
if (show) {
nv_error(priv, "PBDMA%d:", unit);
nouveau_bitfield_print(nvc0_fifo_pbdma_intr, show);
pr_cont("\n");
nv_error(priv,
"PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
unit, chid,
nouveau_client_name_for_fifo_chid(&priv->base, chid),
subc, mthd, data);
}
nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
}
static void
nvc0_fifo_intr_runlist(struct nvc0_fifo_priv *priv)
{
u32 intr = nv_rd32(priv, 0x002a00);
if (intr & 0x10000000) {
wake_up(&priv->runlist.wait);
nv_wr32(priv, 0x002a00, 0x10000000);
intr &= ~0x10000000;
}
if (intr) {
nv_error(priv, "RUNLIST 0x%08x\n", intr);
nv_wr32(priv, 0x002a00, intr);
}
}
static void
nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
{
u32 intr = nv_rd32(priv, 0x0025a8 + (engn * 0x04));
u32 inte = nv_rd32(priv, 0x002628);
u32 unkn;
for (unkn = 0; unkn < 8; unkn++) {
u32 ints = (intr >> (unkn * 0x04)) & inte;
if (ints & 0x1) {
nouveau_event_trigger(priv->base.uevent, 0);
ints &= ~1;
}
if (ints) {
nv_error(priv, "ENGINE %d %d %01x", engn, unkn, ints);
nv_mask(priv, 0x002628, ints, 0);
}
}
nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr);
}
static void
nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv)
{
u32 mask = nv_rd32(priv, 0x0025a4);
while (mask) {
u32 unit = __ffs(mask);
nvc0_fifo_intr_engine_unit(priv, unit);
mask &= ~(1 << unit);
}
}
static void
nvc0_fifo_intr(struct nouveau_subdev *subdev)
{
struct nvc0_fifo_priv *priv = (void *)subdev;
u32 mask = nv_rd32(priv, 0x002140);
u32 stat = nv_rd32(priv, 0x002100) & mask;
if (stat & 0x00000001) {
u32 intr = nv_rd32(priv, 0x00252c);
nv_warn(priv, "INTR 0x00000001: 0x%08x\n", intr);
nv_wr32(priv, 0x002100, 0x00000001);
stat &= ~0x00000001;
}
if (stat & 0x00000100) {
nvc0_fifo_intr_sched(priv);
nv_wr32(priv, 0x002100, 0x00000100);
stat &= ~0x00000100;
}
if (stat & 0x00010000) {
u32 intr = nv_rd32(priv, 0x00256c);
nv_warn(priv, "INTR 0x00010000: 0x%08x\n", intr);
nv_wr32(priv, 0x002100, 0x00010000);
stat &= ~0x00010000;
}
if (stat & 0x01000000) {
u32 intr = nv_rd32(priv, 0x00258c);
nv_warn(priv, "INTR 0x01000000: 0x%08x\n", intr);
nv_wr32(priv, 0x002100, 0x01000000);
stat &= ~0x01000000;
}
if (stat & 0x10000000) {
u32 mask = nv_rd32(priv, 0x00259c);
while (mask) {
u32 unit = __ffs(mask);
nvc0_fifo_intr_fault(priv, unit);
nv_wr32(priv, 0x00259c, (1 << unit));
mask &= ~(1 << unit);
}
stat &= ~0x10000000;
}
if (stat & 0x20000000) {
u32 mask = nv_rd32(priv, 0x0025a0);
while (mask) {
u32 unit = __ffs(mask);
nvc0_fifo_intr_pbdma(priv, unit);
nv_wr32(priv, 0x0025a0, (1 << unit));
mask &= ~(1 << unit);
}
stat &= ~0x20000000;
}
if (stat & 0x40000000) {
nvc0_fifo_intr_runlist(priv);
stat &= ~0x40000000;
}
if (stat & 0x80000000) {
nvc0_fifo_intr_engine(priv);
stat &= ~0x80000000;
}
if (stat) {
nv_error(priv, "INTR 0x%08x\n", stat);
nv_mask(priv, 0x002140, stat, 0x00000000);
nv_wr32(priv, 0x002100, stat);
}
}
static void
nvc0_fifo_uevent_enable(struct nouveau_event *event, int index)
{
struct nvc0_fifo_priv *priv = event->priv;
nv_mask(priv, 0x002140, 0x80000000, 0x80000000);
}
static void
nvc0_fifo_uevent_disable(struct nouveau_event *event, int index)
{
struct nvc0_fifo_priv *priv = event->priv;
nv_mask(priv, 0x002140, 0x80000000, 0x00000000);
}
static int
nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject)
{
struct nvc0_fifo_priv *priv;
int ret;
ret = nouveau_fifo_create(parent, engine, oclass, 0, 127, &priv);
*pobject = nv_object(priv);
if (ret)
return ret;
INIT_WORK(&priv->fault, nvc0_fifo_recover_work);
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
&priv->runlist.mem[0]);
if (ret)
return ret;
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
&priv->runlist.mem[1]);
if (ret)
return ret;
init_waitqueue_head(&priv->runlist.wait);
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0,
&priv->user.mem);
if (ret)
return ret;
ret = nouveau_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW,
&priv->user.bar);
if (ret)
return ret;
priv->base.uevent->enable = nvc0_fifo_uevent_enable;
priv->base.uevent->disable = nvc0_fifo_uevent_disable;
priv->base.uevent->priv = priv;
nv_subdev(priv)->unit = 0x00000100;
nv_subdev(priv)->intr = nvc0_fifo_intr;
nv_engine(priv)->cclass = &nvc0_fifo_cclass;
nv_engine(priv)->sclass = nvc0_fifo_sclass;
return 0;
}
static void
nvc0_fifo_dtor(struct nouveau_object *object)
{
struct nvc0_fifo_priv *priv = (void *)object;
nouveau_gpuobj_unmap(&priv->user.bar);
nouveau_gpuobj_ref(NULL, &priv->user.mem);
nouveau_gpuobj_ref(NULL, &priv->runlist.mem[0]);
nouveau_gpuobj_ref(NULL, &priv->runlist.mem[1]);
nouveau_fifo_destroy(&priv->base);
}
static int
nvc0_fifo_init(struct nouveau_object *object)
{
struct nvc0_fifo_priv *priv = (void *)object;
int ret, i;
ret = nouveau_fifo_init(&priv->base);
if (ret)
return ret;
nv_wr32(priv, 0x000204, 0xffffffff);
nv_wr32(priv, 0x002204, 0xffffffff);
priv->spoon_nr = hweight32(nv_rd32(priv, 0x002204));
nv_debug(priv, "%d PBDMA unit(s)\n", priv->spoon_nr);
/* assign engines to PBDMAs */
if (priv->spoon_nr >= 3) {
nv_wr32(priv, 0x002208, ~(1 << 0)); /* PGRAPH */
nv_wr32(priv, 0x00220c, ~(1 << 1)); /* PVP */
nv_wr32(priv, 0x002210, ~(1 << 1)); /* PPP */
nv_wr32(priv, 0x002214, ~(1 << 1)); /* PBSP */
nv_wr32(priv, 0x002218, ~(1 << 2)); /* PCE0 */
nv_wr32(priv, 0x00221c, ~(1 << 1)); /* PCE1 */
}
/* PBDMA[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_mask(priv, 0x002200, 0x00000001, 0x00000001);
nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
nv_wr32(priv, 0x002100, 0xffffffff);
nv_wr32(priv, 0x002140, 0x7fffffff);
nv_wr32(priv, 0x002628, 0x00000001); /* ENGINE_INTR_EN */
return 0;
}
struct nouveau_oclass *
nvc0_fifo_oclass = &(struct nouveau_oclass) {
.handle = NV_ENGINE(FIFO, 0xc0),
.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_fifo_ctor,
.dtor = nvc0_fifo_dtor,
.init = nvc0_fifo_init,
.fini = _nouveau_fifo_fini,
},
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
#ifndef __NVKM_FIFO_NVE0_H__
#define __NVKM_FIFO_NVE0_H__
#include <engine/fifo.h>
int nve0_fifo_ctor(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, void *, u32,
struct nouveau_object **);
void nve0_fifo_dtor(struct nouveau_object *);
int nve0_fifo_init(struct nouveau_object *);
struct nve0_fifo_impl {
struct nouveau_oclass base;
u32 channels;
};
#endif

View File

@ -0,0 +1,129 @@
#ifndef __NOUVEAU_GRCTX_H__
#define __NOUVEAU_GRCTX_H__
struct nouveau_grctx {
struct nouveau_device *device;
enum {
NOUVEAU_GRCTX_PROG,
NOUVEAU_GRCTX_VALS
} mode;
void *data;
u32 ctxprog_max;
u32 ctxprog_len;
u32 ctxprog_reg;
int ctxprog_label[32];
u32 ctxvals_pos;
u32 ctxvals_base;
};
static inline void
cp_out(struct nouveau_grctx *ctx, u32 inst)
{
u32 *ctxprog = ctx->data;
if (ctx->mode != NOUVEAU_GRCTX_PROG)
return;
BUG_ON(ctx->ctxprog_len == ctx->ctxprog_max);
ctxprog[ctx->ctxprog_len++] = inst;
}
static inline void
cp_lsr(struct nouveau_grctx *ctx, u32 val)
{
cp_out(ctx, CP_LOAD_SR | val);
}
static inline void
cp_ctx(struct nouveau_grctx *ctx, u32 reg, u32 length)
{
ctx->ctxprog_reg = (reg - 0x00400000) >> 2;
ctx->ctxvals_base = ctx->ctxvals_pos;
ctx->ctxvals_pos = ctx->ctxvals_base + length;
if (length > (CP_CTX_COUNT >> CP_CTX_COUNT_SHIFT)) {
cp_lsr(ctx, length);
length = 0;
}
cp_out(ctx, CP_CTX | (length << CP_CTX_COUNT_SHIFT) | ctx->ctxprog_reg);
}
static inline void
cp_name(struct nouveau_grctx *ctx, int name)
{
u32 *ctxprog = ctx->data;
int i;
if (ctx->mode != NOUVEAU_GRCTX_PROG)
return;
ctx->ctxprog_label[name] = ctx->ctxprog_len;
for (i = 0; i < ctx->ctxprog_len; i++) {
if ((ctxprog[i] & 0xfff00000) != 0xff400000)
continue;
if ((ctxprog[i] & CP_BRA_IP) != ((name) << CP_BRA_IP_SHIFT))
continue;
ctxprog[i] = (ctxprog[i] & 0x00ff00ff) |
(ctx->ctxprog_len << CP_BRA_IP_SHIFT);
}
}
static inline void
_cp_bra(struct nouveau_grctx *ctx, u32 mod, int flag, int state, int name)
{
int ip = 0;
if (mod != 2) {
ip = ctx->ctxprog_label[name] << CP_BRA_IP_SHIFT;
if (ip == 0)
ip = 0xff000000 | (name << CP_BRA_IP_SHIFT);
}
cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
(state ? 0 : CP_BRA_IF_CLEAR));
}
#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
static inline void
_cp_wait(struct nouveau_grctx *ctx, int flag, int state)
{
cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
}
#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
static inline void
_cp_set(struct nouveau_grctx *ctx, int flag, int state)
{
cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
}
#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
static inline void
cp_pos(struct nouveau_grctx *ctx, int offset)
{
ctx->ctxvals_pos = offset;
ctx->ctxvals_base = ctx->ctxvals_pos;
cp_lsr(ctx, ctx->ctxvals_pos);
cp_out(ctx, CP_SET_CONTEXT_POINTER);
}
static inline void
gr_def(struct nouveau_grctx *ctx, u32 reg, u32 val)
{
if (ctx->mode != NOUVEAU_GRCTX_VALS)
return;
reg = (reg - 0x00400000) / 4;
reg = (reg - ctx->ctxprog_reg) + ctx->ctxvals_base;
nv_wo32(ctx->data, reg * 4, val);
}
#endif

View File

@ -0,0 +1,991 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
gm107_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
{ 0x00003d, 1, 0x01, 0x00000001 },
{ 0x0000e8, 8, 0x01, 0x00000400 },
{ 0x000078, 8, 0x01, 0x00000300 },
{ 0x000050, 1, 0x01, 0x00000011 },
{ 0x000058, 8, 0x01, 0x00000008 },
{ 0x000208, 8, 0x01, 0x00000001 },
{ 0x000081, 1, 0x01, 0x00000001 },
{ 0x000085, 1, 0x01, 0x00000004 },
{ 0x000088, 1, 0x01, 0x00000400 },
{ 0x000090, 1, 0x01, 0x00000300 },
{ 0x000098, 1, 0x01, 0x00001001 },
{ 0x0000e3, 1, 0x01, 0x00000001 },
{ 0x0000da, 1, 0x01, 0x00000001 },
{ 0x0000f8, 1, 0x01, 0x00000003 },
{ 0x0000fa, 1, 0x01, 0x00000001 },
{ 0x0000b1, 2, 0x01, 0x00000001 },
{ 0x00009f, 4, 0x01, 0x0000ffff },
{ 0x0000a8, 1, 0x01, 0x0000ffff },
{ 0x0000ad, 1, 0x01, 0x0000013e },
{ 0x0000e1, 1, 0x01, 0x00000010 },
{ 0x000290, 16, 0x01, 0x00000000 },
{ 0x0003b0, 16, 0x01, 0x00000000 },
{ 0x0002a0, 16, 0x01, 0x00000000 },
{ 0x000420, 16, 0x01, 0x00000000 },
{ 0x0002b0, 16, 0x01, 0x00000000 },
{ 0x000430, 16, 0x01, 0x00000000 },
{ 0x0002c0, 16, 0x01, 0x00000000 },
{ 0x0004d0, 16, 0x01, 0x00000000 },
{ 0x000720, 16, 0x01, 0x00000000 },
{ 0x0008c0, 16, 0x01, 0x00000000 },
{ 0x000890, 16, 0x01, 0x00000000 },
{ 0x0008e0, 16, 0x01, 0x00000000 },
{ 0x0008a0, 16, 0x01, 0x00000000 },
{ 0x0008f0, 16, 0x01, 0x00000000 },
{ 0x00094c, 1, 0x01, 0x000000ff },
{ 0x00094d, 1, 0x01, 0xffffffff },
{ 0x00094e, 1, 0x01, 0x00000002 },
{ 0x0002f2, 2, 0x01, 0x00000001 },
{ 0x0002f5, 1, 0x01, 0x00000001 },
{ 0x0002f7, 1, 0x01, 0x00000001 },
{ 0x000303, 1, 0x01, 0x00000001 },
{ 0x0002e6, 1, 0x01, 0x00000001 },
{ 0x000466, 1, 0x01, 0x00000052 },
{ 0x000301, 1, 0x01, 0x3f800000 },
{ 0x000304, 1, 0x01, 0x30201000 },
{ 0x000305, 1, 0x01, 0x70605040 },
{ 0x000306, 1, 0x01, 0xb8a89888 },
{ 0x000307, 1, 0x01, 0xf8e8d8c8 },
{ 0x00030a, 1, 0x01, 0x00ffff00 },
{ 0x0000de, 1, 0x01, 0x00000001 },
{ 0x00030b, 1, 0x01, 0x0000001a },
{ 0x00030c, 1, 0x01, 0x00000001 },
{ 0x000318, 1, 0x01, 0x00000001 },
{ 0x000340, 1, 0x01, 0x00000000 },
{ 0x00037d, 1, 0x01, 0x00000006 },
{ 0x0003a0, 1, 0x01, 0x00000002 },
{ 0x0003aa, 1, 0x01, 0x00000001 },
{ 0x0003a9, 1, 0x01, 0x00000001 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000383, 1, 0x01, 0x00000011 },
{ 0x000360, 1, 0x01, 0x00000040 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00000fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x000fffff },
{ 0x00037a, 1, 0x01, 0x00000012 },
{ 0x000619, 1, 0x01, 0x00000003 },
{ 0x000811, 1, 0x01, 0x00000003 },
{ 0x000812, 1, 0x01, 0x00000004 },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000815, 1, 0x01, 0x0000000b },
{ 0x000800, 6, 0x01, 0x00000001 },
{ 0x000632, 1, 0x01, 0x00000001 },
{ 0x000633, 1, 0x01, 0x00000002 },
{ 0x000634, 1, 0x01, 0x00000003 },
{ 0x000635, 1, 0x01, 0x00000004 },
{ 0x000654, 1, 0x01, 0x3f800000 },
{ 0x000657, 1, 0x01, 0x3f800000 },
{ 0x000655, 2, 0x01, 0x3f800000 },
{ 0x0006cd, 1, 0x01, 0x3f800000 },
{ 0x0007f5, 1, 0x01, 0x3f800000 },
{ 0x0007dc, 1, 0x01, 0x39291909 },
{ 0x0007dd, 1, 0x01, 0x79695949 },
{ 0x0007de, 1, 0x01, 0xb9a99989 },
{ 0x0007df, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007e8, 1, 0x01, 0x00003210 },
{ 0x0007e9, 1, 0x01, 0x00007654 },
{ 0x0007ea, 1, 0x01, 0x00000098 },
{ 0x0007ec, 1, 0x01, 0x39291909 },
{ 0x0007ed, 1, 0x01, 0x79695949 },
{ 0x0007ee, 1, 0x01, 0xb9a99989 },
{ 0x0007ef, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007f0, 1, 0x01, 0x00003210 },
{ 0x0007f1, 1, 0x01, 0x00007654 },
{ 0x0007f2, 1, 0x01, 0x00000098 },
{ 0x0005a5, 1, 0x01, 0x00000001 },
{ 0x0005d0, 1, 0x01, 0x20181008 },
{ 0x0005d1, 1, 0x01, 0x40383028 },
{ 0x0005d2, 1, 0x01, 0x60585048 },
{ 0x0005d3, 1, 0x01, 0x80787068 },
{ 0x000980, 128, 0x01, 0x00000000 },
{ 0x000468, 1, 0x01, 0x00000004 },
{ 0x00046c, 1, 0x01, 0x00000001 },
{ 0x000470, 96, 0x01, 0x00000000 },
{ 0x000510, 16, 0x01, 0x3f800000 },
{ 0x000520, 1, 0x01, 0x000002b6 },
{ 0x000529, 1, 0x01, 0x00000001 },
{ 0x000530, 16, 0x01, 0xffff0000 },
{ 0x000550, 32, 0x01, 0xffff0000 },
{ 0x000585, 1, 0x01, 0x0000003f },
{ 0x000576, 1, 0x01, 0x00000003 },
{ 0x00057b, 1, 0x01, 0x00000059 },
{ 0x000586, 1, 0x01, 0x00000040 },
{ 0x000582, 2, 0x01, 0x00000080 },
{ 0x000595, 1, 0x01, 0x00400040 },
{ 0x000596, 1, 0x01, 0x00000492 },
{ 0x000597, 1, 0x01, 0x08080203 },
{ 0x0005ad, 1, 0x01, 0x00000008 },
{ 0x000598, 1, 0x01, 0x00020001 },
{ 0x0005c2, 1, 0x01, 0x00000001 },
{ 0x000638, 2, 0x01, 0x00000001 },
{ 0x00063a, 1, 0x01, 0x00000002 },
{ 0x00063b, 2, 0x01, 0x00000001 },
{ 0x00063d, 1, 0x01, 0x00000002 },
{ 0x00063e, 1, 0x01, 0x00000001 },
{ 0x0008b8, 8, 0x01, 0x00000001 },
{ 0x000900, 8, 0x01, 0x00000001 },
{ 0x000908, 8, 0x01, 0x00000002 },
{ 0x000910, 16, 0x01, 0x00000001 },
{ 0x000920, 8, 0x01, 0x00000002 },
{ 0x000928, 8, 0x01, 0x00000001 },
{ 0x000662, 1, 0x01, 0x00000001 },
{ 0x000648, 9, 0x01, 0x00000001 },
{ 0x000658, 1, 0x01, 0x0000000f },
{ 0x0007ff, 1, 0x01, 0x0000000a },
{ 0x00066a, 1, 0x01, 0x40000000 },
{ 0x00066b, 1, 0x01, 0x10000000 },
{ 0x00066c, 2, 0x01, 0xffff0000 },
{ 0x0007af, 2, 0x01, 0x00000008 },
{ 0x0007f6, 1, 0x01, 0x00000001 },
{ 0x0006b2, 1, 0x01, 0x00000055 },
{ 0x0007ad, 1, 0x01, 0x00000003 },
{ 0x000971, 1, 0x01, 0x00000008 },
{ 0x000972, 1, 0x01, 0x00000040 },
{ 0x000973, 1, 0x01, 0x0000012c },
{ 0x00097c, 1, 0x01, 0x00000040 },
{ 0x000975, 1, 0x01, 0x00000020 },
{ 0x000976, 1, 0x01, 0x00000001 },
{ 0x000977, 1, 0x01, 0x00000020 },
{ 0x000978, 1, 0x01, 0x00000001 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095e, 1, 0x01, 0x20164010 },
{ 0x00095f, 1, 0x01, 0x00000020 },
{ 0x000a0d, 1, 0x01, 0x00000006 },
{ 0x00097d, 1, 0x01, 0x0000000c },
{ 0x000683, 1, 0x01, 0x00000006 },
{ 0x000687, 1, 0x01, 0x003fffff },
{ 0x0006a0, 1, 0x01, 0x00000005 },
{ 0x000840, 1, 0x01, 0x00400008 },
{ 0x000841, 1, 0x01, 0x08000080 },
{ 0x000842, 1, 0x01, 0x00400008 },
{ 0x000843, 1, 0x01, 0x08000080 },
{ 0x000818, 8, 0x01, 0x00000000 },
{ 0x000848, 16, 0x01, 0x00000000 },
{ 0x000738, 1, 0x01, 0x00000000 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ab, 1, 0x01, 0x00000002 },
{ 0x0006ac, 1, 0x01, 0x00000080 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x0006bb, 1, 0x01, 0x000000cf },
{ 0x0006ce, 1, 0x01, 0x2a712488 },
{ 0x000739, 1, 0x01, 0x4085c000 },
{ 0x00073a, 1, 0x01, 0x00000080 },
{ 0x000786, 1, 0x01, 0x80000100 },
{ 0x00073c, 1, 0x01, 0x00010100 },
{ 0x00073d, 1, 0x01, 0x02800000 },
{ 0x000787, 1, 0x01, 0x000000cf },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x000836, 1, 0x01, 0x00000001 },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x000a04, 1, 0x01, 0x000000ff },
{ 0x000a0b, 1, 0x01, 0x00000040 },
{ 0x00097f, 1, 0x01, 0x00000100 },
{ 0x000a02, 1, 0x01, 0x00000001 },
{ 0x000809, 1, 0x01, 0x00000007 },
{ 0x00c221, 1, 0x01, 0x00000040 },
{ 0x00c1b0, 8, 0x01, 0x0000000f },
{ 0x00c1b8, 1, 0x01, 0x0fac6881 },
{ 0x00c1b9, 1, 0x01, 0x00fac688 },
{ 0x00c401, 1, 0x01, 0x00000001 },
{ 0x00c402, 1, 0x01, 0x00010001 },
{ 0x00c403, 2, 0x01, 0x00000001 },
{ 0x00c40e, 1, 0x01, 0x00000020 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000002 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000008 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00000fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x000fffff },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000818, 8, 0x01, 0x00000000 },
{ 0x000848, 16, 0x01, 0x00000000 },
{ 0x000738, 1, 0x01, 0x00000000 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x000a04, 1, 0x01, 0x000000ff },
{ 0x000a0b, 1, 0x01, 0x00000040 },
{ 0x00097f, 1, 0x01, 0x00000100 },
{ 0x000a02, 1, 0x01, 0x00000001 },
{ 0x000809, 1, 0x01, 0x00000007 },
{ 0x00c221, 1, 0x01, 0x00000040 },
{ 0x00c401, 1, 0x01, 0x00000001 },
{ 0x00c402, 1, 0x01, 0x00010001 },
{ 0x00c403, 2, 0x01, 0x00000001 },
{ 0x00c40e, 1, 0x01, 0x00000020 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000001 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
gm107_grctx_pack_icmd[] = {
{ gm107_grctx_init_icmd_0 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_b097_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
{ 0x00080c, 8, 0x40, 0x00000300 },
{ 0x000810, 1, 0x04, 0x000000cf },
{ 0x000850, 7, 0x40, 0x00000000 },
{ 0x000814, 8, 0x40, 0x00000040 },
{ 0x000818, 8, 0x40, 0x00000001 },
{ 0x00081c, 8, 0x40, 0x00000000 },
{ 0x000820, 8, 0x40, 0x00000000 },
{ 0x001c00, 16, 0x10, 0x00000000 },
{ 0x001c04, 16, 0x10, 0x00000000 },
{ 0x001c08, 16, 0x10, 0x00000000 },
{ 0x001c0c, 16, 0x10, 0x00000000 },
{ 0x001d00, 16, 0x10, 0x00000000 },
{ 0x001d04, 16, 0x10, 0x00000000 },
{ 0x001d08, 16, 0x10, 0x00000000 },
{ 0x001d0c, 16, 0x10, 0x00000000 },
{ 0x001f00, 16, 0x08, 0x00000000 },
{ 0x001f04, 16, 0x08, 0x00000000 },
{ 0x001f80, 16, 0x08, 0x00000000 },
{ 0x001f84, 16, 0x08, 0x00000000 },
{ 0x002000, 1, 0x04, 0x00000000 },
{ 0x002040, 1, 0x04, 0x00000011 },
{ 0x002080, 1, 0x04, 0x00000020 },
{ 0x0020c0, 1, 0x04, 0x00000030 },
{ 0x002100, 1, 0x04, 0x00000040 },
{ 0x002140, 1, 0x04, 0x00000051 },
{ 0x00200c, 6, 0x40, 0x00000001 },
{ 0x002010, 1, 0x04, 0x00000000 },
{ 0x002050, 1, 0x04, 0x00000000 },
{ 0x002090, 1, 0x04, 0x00000001 },
{ 0x0020d0, 1, 0x04, 0x00000002 },
{ 0x002110, 1, 0x04, 0x00000003 },
{ 0x002150, 1, 0x04, 0x00000004 },
{ 0x000380, 4, 0x20, 0x00000000 },
{ 0x000384, 4, 0x20, 0x00000000 },
{ 0x000388, 4, 0x20, 0x00000000 },
{ 0x00038c, 4, 0x20, 0x00000000 },
{ 0x000700, 4, 0x10, 0x00000000 },
{ 0x000704, 4, 0x10, 0x00000000 },
{ 0x000708, 4, 0x10, 0x00000000 },
{ 0x002800, 128, 0x04, 0x00000000 },
{ 0x000a00, 16, 0x20, 0x00000000 },
{ 0x000a04, 16, 0x20, 0x00000000 },
{ 0x000a08, 16, 0x20, 0x00000000 },
{ 0x000a0c, 16, 0x20, 0x00000000 },
{ 0x000a10, 16, 0x20, 0x00000000 },
{ 0x000a14, 16, 0x20, 0x00000000 },
{ 0x000c00, 16, 0x10, 0x00000000 },
{ 0x000c04, 16, 0x10, 0x00000000 },
{ 0x000c08, 16, 0x10, 0x00000000 },
{ 0x000c0c, 16, 0x10, 0x3f800000 },
{ 0x000d00, 8, 0x08, 0xffff0000 },
{ 0x000d04, 8, 0x08, 0xffff0000 },
{ 0x000e00, 16, 0x10, 0x00000000 },
{ 0x000e04, 16, 0x10, 0xffff0000 },
{ 0x000e08, 16, 0x10, 0xffff0000 },
{ 0x000d40, 4, 0x08, 0x00000000 },
{ 0x000d44, 4, 0x08, 0x00000000 },
{ 0x001e00, 8, 0x20, 0x00000001 },
{ 0x001e04, 8, 0x20, 0x00000001 },
{ 0x001e08, 8, 0x20, 0x00000002 },
{ 0x001e0c, 8, 0x20, 0x00000001 },
{ 0x001e10, 8, 0x20, 0x00000001 },
{ 0x001e14, 8, 0x20, 0x00000002 },
{ 0x001e18, 8, 0x20, 0x00000001 },
{ 0x001480, 8, 0x10, 0x00000000 },
{ 0x001484, 8, 0x10, 0x00000000 },
{ 0x001488, 8, 0x10, 0x00000000 },
{ 0x003400, 128, 0x04, 0x00000000 },
{ 0x00030c, 1, 0x04, 0x00000001 },
{ 0x001944, 1, 0x04, 0x00000000 },
{ 0x001514, 1, 0x04, 0x00000000 },
{ 0x000d68, 1, 0x04, 0x0000ffff },
{ 0x00121c, 1, 0x04, 0x0fac6881 },
{ 0x000fac, 1, 0x04, 0x00000001 },
{ 0x001538, 1, 0x04, 0x00000001 },
{ 0x000fe0, 2, 0x04, 0x00000000 },
{ 0x000fe8, 1, 0x04, 0x00000014 },
{ 0x000fec, 1, 0x04, 0x00000040 },
{ 0x000ff0, 1, 0x04, 0x00000000 },
{ 0x00179c, 1, 0x04, 0x00000000 },
{ 0x001228, 1, 0x04, 0x00000400 },
{ 0x00122c, 1, 0x04, 0x00000300 },
{ 0x001230, 1, 0x04, 0x00010001 },
{ 0x0007f8, 1, 0x04, 0x00000000 },
{ 0x0015b4, 1, 0x04, 0x00000001 },
{ 0x0015cc, 1, 0x04, 0x00000000 },
{ 0x001534, 1, 0x04, 0x00000000 },
{ 0x000754, 1, 0x04, 0x00000001 },
{ 0x000fb0, 1, 0x04, 0x00000000 },
{ 0x0015d0, 1, 0x04, 0x00000000 },
{ 0x00153c, 1, 0x04, 0x00000000 },
{ 0x0016b4, 1, 0x04, 0x00000003 },
{ 0x000fbc, 4, 0x04, 0x0000ffff },
{ 0x000df8, 2, 0x04, 0x00000000 },
{ 0x001948, 1, 0x04, 0x00000000 },
{ 0x001970, 1, 0x04, 0x00000001 },
{ 0x00161c, 1, 0x04, 0x000009f0 },
{ 0x000dcc, 1, 0x04, 0x00000010 },
{ 0x0015e4, 1, 0x04, 0x00000000 },
{ 0x001160, 32, 0x04, 0x25e00040 },
{ 0x001880, 32, 0x04, 0x00000000 },
{ 0x000f84, 2, 0x04, 0x00000000 },
{ 0x0017c8, 2, 0x04, 0x00000000 },
{ 0x0017d0, 1, 0x04, 0x000000ff },
{ 0x0017d4, 1, 0x04, 0xffffffff },
{ 0x0017d8, 1, 0x04, 0x00000002 },
{ 0x0017dc, 1, 0x04, 0x00000000 },
{ 0x0015f4, 2, 0x04, 0x00000000 },
{ 0x001434, 2, 0x04, 0x00000000 },
{ 0x000d74, 1, 0x04, 0x00000000 },
{ 0x0013a4, 1, 0x04, 0x00000000 },
{ 0x001318, 1, 0x04, 0x00000001 },
{ 0x001080, 2, 0x04, 0x00000000 },
{ 0x001088, 2, 0x04, 0x00000001 },
{ 0x001090, 1, 0x04, 0x00000000 },
{ 0x001094, 1, 0x04, 0x00000001 },
{ 0x001098, 1, 0x04, 0x00000000 },
{ 0x00109c, 1, 0x04, 0x00000001 },
{ 0x0010a0, 2, 0x04, 0x00000000 },
{ 0x001644, 1, 0x04, 0x00000000 },
{ 0x000748, 1, 0x04, 0x00000000 },
{ 0x000de8, 1, 0x04, 0x00000000 },
{ 0x001648, 1, 0x04, 0x00000000 },
{ 0x0012a4, 1, 0x04, 0x00000000 },
{ 0x001120, 4, 0x04, 0x00000000 },
{ 0x001118, 1, 0x04, 0x00000000 },
{ 0x00164c, 1, 0x04, 0x00000000 },
{ 0x001658, 1, 0x04, 0x00000000 },
{ 0x001910, 1, 0x04, 0x00000290 },
{ 0x001518, 1, 0x04, 0x00000000 },
{ 0x00165c, 1, 0x04, 0x00000001 },
{ 0x001520, 1, 0x04, 0x00000000 },
{ 0x001604, 1, 0x04, 0x00000000 },
{ 0x001570, 1, 0x04, 0x00000000 },
{ 0x0013b0, 2, 0x04, 0x3f800000 },
{ 0x00020c, 1, 0x04, 0x00000000 },
{ 0x001670, 1, 0x04, 0x30201000 },
{ 0x001674, 1, 0x04, 0x70605040 },
{ 0x001678, 1, 0x04, 0xb8a89888 },
{ 0x00167c, 1, 0x04, 0xf8e8d8c8 },
{ 0x00166c, 1, 0x04, 0x00000000 },
{ 0x001680, 1, 0x04, 0x00ffff00 },
{ 0x0012d0, 1, 0x04, 0x00000003 },
{ 0x0012d4, 1, 0x04, 0x00000002 },
{ 0x001684, 2, 0x04, 0x00000000 },
{ 0x000dac, 2, 0x04, 0x00001b02 },
{ 0x000db4, 1, 0x04, 0x00000000 },
{ 0x00168c, 1, 0x04, 0x00000000 },
{ 0x0015bc, 1, 0x04, 0x00000000 },
{ 0x00156c, 1, 0x04, 0x00000000 },
{ 0x00187c, 1, 0x04, 0x00000000 },
{ 0x001110, 1, 0x04, 0x00000001 },
{ 0x000dc0, 3, 0x04, 0x00000000 },
{ 0x000f40, 5, 0x04, 0x00000000 },
{ 0x001234, 1, 0x04, 0x00000000 },
{ 0x001690, 1, 0x04, 0x00000000 },
{ 0x000790, 5, 0x04, 0x00000000 },
{ 0x00077c, 1, 0x04, 0x00000000 },
{ 0x001000, 1, 0x04, 0x00000010 },
{ 0x0010fc, 1, 0x04, 0x00000000 },
{ 0x001290, 1, 0x04, 0x00000000 },
{ 0x000218, 1, 0x04, 0x00000010 },
{ 0x0012d8, 1, 0x04, 0x00000000 },
{ 0x0012dc, 1, 0x04, 0x00000010 },
{ 0x000d94, 1, 0x04, 0x00000001 },
{ 0x00155c, 2, 0x04, 0x00000000 },
{ 0x001564, 1, 0x04, 0x00000fff },
{ 0x001574, 2, 0x04, 0x00000000 },
{ 0x00157c, 1, 0x04, 0x000fffff },
{ 0x001354, 1, 0x04, 0x00000000 },
{ 0x001610, 1, 0x04, 0x00000012 },
{ 0x001608, 2, 0x04, 0x00000000 },
{ 0x00260c, 1, 0x04, 0x00000000 },
{ 0x0007ac, 1, 0x04, 0x00000000 },
{ 0x00162c, 1, 0x04, 0x00000003 },
{ 0x000210, 1, 0x04, 0x00000000 },
{ 0x000320, 1, 0x04, 0x00000000 },
{ 0x000324, 6, 0x04, 0x3f800000 },
{ 0x000750, 1, 0x04, 0x00000000 },
{ 0x000760, 1, 0x04, 0x39291909 },
{ 0x000764, 1, 0x04, 0x79695949 },
{ 0x000768, 1, 0x04, 0xb9a99989 },
{ 0x00076c, 1, 0x04, 0xf9e9d9c9 },
{ 0x000770, 1, 0x04, 0x30201000 },
{ 0x000774, 1, 0x04, 0x70605040 },
{ 0x000778, 1, 0x04, 0x00009080 },
{ 0x000780, 1, 0x04, 0x39291909 },
{ 0x000784, 1, 0x04, 0x79695949 },
{ 0x000788, 1, 0x04, 0xb9a99989 },
{ 0x00078c, 1, 0x04, 0xf9e9d9c9 },
{ 0x0007d0, 1, 0x04, 0x30201000 },
{ 0x0007d4, 1, 0x04, 0x70605040 },
{ 0x0007d8, 1, 0x04, 0x00009080 },
{ 0x00037c, 1, 0x04, 0x00000001 },
{ 0x000740, 2, 0x04, 0x00000000 },
{ 0x002600, 1, 0x04, 0x00000000 },
{ 0x001918, 1, 0x04, 0x00000000 },
{ 0x00191c, 1, 0x04, 0x00000900 },
{ 0x001920, 1, 0x04, 0x00000405 },
{ 0x001308, 1, 0x04, 0x00000001 },
{ 0x001924, 1, 0x04, 0x00000000 },
{ 0x0013ac, 1, 0x04, 0x00000000 },
{ 0x00192c, 1, 0x04, 0x00000001 },
{ 0x00193c, 1, 0x04, 0x00002c1c },
{ 0x000d7c, 1, 0x04, 0x00000000 },
{ 0x000f8c, 1, 0x04, 0x00000000 },
{ 0x0002c0, 1, 0x04, 0x00000001 },
{ 0x001510, 1, 0x04, 0x00000000 },
{ 0x001940, 1, 0x04, 0x00000000 },
{ 0x000ff4, 2, 0x04, 0x00000000 },
{ 0x00194c, 2, 0x04, 0x00000000 },
{ 0x001968, 1, 0x04, 0x00000000 },
{ 0x001590, 1, 0x04, 0x0000003f },
{ 0x0007e8, 4, 0x04, 0x00000000 },
{ 0x00196c, 1, 0x04, 0x00000011 },
{ 0x0002e4, 1, 0x04, 0x0000b001 },
{ 0x00036c, 2, 0x04, 0x00000000 },
{ 0x00197c, 1, 0x04, 0x00000000 },
{ 0x000fcc, 2, 0x04, 0x00000000 },
{ 0x0002d8, 1, 0x04, 0x00000040 },
{ 0x001980, 1, 0x04, 0x00000080 },
{ 0x001504, 1, 0x04, 0x00000080 },
{ 0x001984, 1, 0x04, 0x00000000 },
{ 0x000f60, 1, 0x04, 0x00000000 },
{ 0x000f64, 1, 0x04, 0x00400040 },
{ 0x000f68, 1, 0x04, 0x00002212 },
{ 0x000f6c, 1, 0x04, 0x08080203 },
{ 0x001108, 1, 0x04, 0x00000008 },
{ 0x000f70, 1, 0x04, 0x00080001 },
{ 0x000ffc, 1, 0x04, 0x00000000 },
{ 0x000300, 1, 0x04, 0x00000001 },
{ 0x0013a8, 1, 0x04, 0x00000000 },
{ 0x0012ec, 1, 0x04, 0x00000000 },
{ 0x001310, 1, 0x04, 0x00000000 },
{ 0x001314, 1, 0x04, 0x00000001 },
{ 0x001380, 1, 0x04, 0x00000000 },
{ 0x001384, 4, 0x04, 0x00000001 },
{ 0x001394, 1, 0x04, 0x00000000 },
{ 0x00139c, 1, 0x04, 0x00000000 },
{ 0x001398, 1, 0x04, 0x00000000 },
{ 0x001594, 1, 0x04, 0x00000000 },
{ 0x001598, 4, 0x04, 0x00000001 },
{ 0x000f54, 3, 0x04, 0x00000000 },
{ 0x0019bc, 1, 0x04, 0x00000000 },
{ 0x000f9c, 2, 0x04, 0x00000000 },
{ 0x0012cc, 1, 0x04, 0x00000000 },
{ 0x0012e8, 1, 0x04, 0x00000000 },
{ 0x00130c, 1, 0x04, 0x00000001 },
{ 0x001360, 8, 0x04, 0x00000000 },
{ 0x00133c, 2, 0x04, 0x00000001 },
{ 0x001344, 1, 0x04, 0x00000002 },
{ 0x001348, 2, 0x04, 0x00000001 },
{ 0x001350, 1, 0x04, 0x00000002 },
{ 0x001358, 1, 0x04, 0x00000001 },
{ 0x0012e4, 1, 0x04, 0x00000000 },
{ 0x00131c, 4, 0x04, 0x00000000 },
{ 0x0019c0, 1, 0x04, 0x00000000 },
{ 0x001140, 1, 0x04, 0x00000000 },
{ 0x000dd0, 1, 0x04, 0x00000000 },
{ 0x000dd4, 1, 0x04, 0x00000001 },
{ 0x0002f4, 1, 0x04, 0x00000000 },
{ 0x0019c4, 1, 0x04, 0x00000000 },
{ 0x0019c8, 1, 0x04, 0x00001500 },
{ 0x00135c, 1, 0x04, 0x00000000 },
{ 0x000f90, 1, 0x04, 0x00000000 },
{ 0x0019e0, 8, 0x04, 0x00000001 },
{ 0x0019cc, 1, 0x04, 0x00000001 },
{ 0x0015b8, 1, 0x04, 0x00000000 },
{ 0x001a00, 1, 0x04, 0x00001111 },
{ 0x001a04, 7, 0x04, 0x00000000 },
{ 0x000d6c, 2, 0x04, 0xffff0000 },
{ 0x0010f8, 1, 0x04, 0x00001010 },
{ 0x000d80, 5, 0x04, 0x00000000 },
{ 0x000da0, 1, 0x04, 0x00000000 },
{ 0x0007a4, 2, 0x04, 0x00000000 },
{ 0x001508, 1, 0x04, 0x80000000 },
{ 0x00150c, 1, 0x04, 0x40000000 },
{ 0x001668, 1, 0x04, 0x00000000 },
{ 0x000318, 2, 0x04, 0x00000008 },
{ 0x000d9c, 1, 0x04, 0x00000001 },
{ 0x000f14, 1, 0x04, 0x00000000 },
{ 0x000374, 1, 0x04, 0x00000000 },
{ 0x000378, 1, 0x04, 0x0000000c },
{ 0x0007dc, 1, 0x04, 0x00000000 },
{ 0x00074c, 1, 0x04, 0x00000055 },
{ 0x001420, 1, 0x04, 0x00000003 },
{ 0x001008, 1, 0x04, 0x00000008 },
{ 0x00100c, 1, 0x04, 0x00000040 },
{ 0x001010, 1, 0x04, 0x0000012c },
{ 0x000d60, 1, 0x04, 0x00000040 },
{ 0x001018, 1, 0x04, 0x00000020 },
{ 0x00101c, 1, 0x04, 0x00000001 },
{ 0x001020, 1, 0x04, 0x00000020 },
{ 0x001024, 1, 0x04, 0x00000001 },
{ 0x001444, 3, 0x04, 0x00000000 },
{ 0x000360, 1, 0x04, 0x20164010 },
{ 0x000364, 1, 0x04, 0x00000020 },
{ 0x000368, 1, 0x04, 0x00000000 },
{ 0x000da8, 1, 0x04, 0x00000030 },
{ 0x000de4, 1, 0x04, 0x00000000 },
{ 0x000204, 1, 0x04, 0x00000006 },
{ 0x0002d0, 1, 0x04, 0x003fffff },
{ 0x001220, 1, 0x04, 0x00000005 },
{ 0x000fdc, 1, 0x04, 0x00000000 },
{ 0x000f98, 1, 0x04, 0x00400008 },
{ 0x001284, 1, 0x04, 0x08000080 },
{ 0x001450, 1, 0x04, 0x00400008 },
{ 0x001454, 1, 0x04, 0x08000080 },
{ 0x000214, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
gm107_grctx_pack_mthd[] = {
{ gm107_grctx_init_b097_0, 0xb097 },
{ nvc0_grctx_init_902d_0, 0x902d },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_fe_0[] = {
{ 0x404004, 8, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
{ 0x404028, 8, 0x04, 0x00000000 },
{ 0x4040a8, 8, 0x04, 0x00000000 },
{ 0x4040c8, 1, 0x04, 0xf800008f },
{ 0x4040d0, 6, 0x04, 0x00000000 },
{ 0x4040f8, 1, 0x04, 0x00000000 },
{ 0x404100, 10, 0x04, 0x00000000 },
{ 0x404130, 2, 0x04, 0x00000000 },
{ 0x404150, 1, 0x04, 0x0000002e },
{ 0x404154, 1, 0x04, 0x00000400 },
{ 0x404158, 1, 0x04, 0x00000200 },
{ 0x404164, 1, 0x04, 0x00000045 },
{ 0x40417c, 2, 0x04, 0x00000000 },
{ 0x404194, 1, 0x04, 0x01000700 },
{ 0x4041a0, 4, 0x04, 0x00000000 },
{ 0x404200, 4, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8001bf },
{ 0x405830, 1, 0x04, 0x0aa01000 },
{ 0x405834, 1, 0x04, 0x08000000 },
{ 0x405838, 1, 0x04, 0x00000000 },
{ 0x405854, 1, 0x04, 0x00000000 },
{ 0x405870, 4, 0x04, 0x00000001 },
{ 0x405a00, 2, 0x04, 0x00000000 },
{ 0x405a18, 1, 0x04, 0x00000000 },
{ 0x405a1c, 1, 0x04, 0x000000ff },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x07410001 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
{ 0x4064ac, 1, 0x04, 0x00003fff },
{ 0x4064b0, 3, 0x04, 0x00000000 },
{ 0x4064c0, 1, 0x04, 0x80400280 },
{ 0x4064c4, 1, 0x04, 0x0400ffff },
{ 0x4064c8, 1, 0x04, 0x018001ff },
{ 0x4064cc, 9, 0x04, 0x00000000 },
{ 0x4064fc, 1, 0x04, 0x0000022a },
{ 0x406500, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x32802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
{ 0x408840, 1, 0x04, 0x0000000b },
{ 0x408900, 1, 0x04, 0xb080b801 },
{ 0x408904, 1, 0x04, 0x63038001 },
{ 0x408908, 1, 0x04, 0x02c8102f },
{ 0x408980, 1, 0x04, 0x0000011d },
{}
};
static const struct nvc0_graph_pack
gm107_grctx_pack_hub[] = {
{ nvc0_grctx_init_main_0 },
{ gm107_grctx_init_fe_0 },
{ nvf0_grctx_init_pri_0 },
{ nve4_grctx_init_memfmt_0 },
{ gm107_grctx_init_ds_0 },
{ nvf0_grctx_init_cwd_0 },
{ gm107_grctx_init_pd_0 },
{ nv108_grctx_init_rstr2d_0 },
{ nve4_grctx_init_scc_0 },
{ gm107_grctx_init_be_0 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_gpc_unk_0[] = {
{ 0x418380, 1, 0x04, 0x00000056 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000007f },
{ 0x418684, 1, 0x04, 0x0000001f },
{ 0x418700, 1, 0x04, 0x00000002 },
{ 0x418704, 1, 0x04, 0x00000080 },
{ 0x418708, 1, 0x04, 0x40000000 },
{ 0x41870c, 2, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006863a },
{ 0x418810, 1, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00000044 },
{ 0x418830, 1, 0x04, 0x10000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x20100058 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_gpc_unk_2[] = {
{ 0x418d24, 1, 0x04, 0x00000000 },
{ 0x418e00, 1, 0x04, 0x90000000 },
{ 0x418e24, 1, 0x04, 0x00000000 },
{ 0x418e28, 1, 0x04, 0x00000030 },
{ 0x418e30, 1, 0x04, 0x00000000 },
{ 0x418e34, 1, 0x04, 0x00010000 },
{ 0x418e38, 1, 0x04, 0x00000000 },
{ 0x418e40, 22, 0x04, 0x00000000 },
{ 0x418ea0, 2, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
gm107_grctx_pack_gpc[] = {
{ gm107_grctx_init_gpc_unk_0 },
{ nv108_grctx_init_prop_0 },
{ gm107_grctx_init_gpc_unk_1 },
{ gm107_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nv108_grctx_init_crstr_0 },
{ nve4_grctx_init_gpm_0 },
{ gm107_grctx_init_gpc_unk_2 },
{ nvc0_grctx_init_gcc_0 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000300f0 },
{ 0x419a04, 1, 0x04, 0x00000005 },
{ 0x419a08, 1, 0x04, 0x00000421 },
{ 0x419a0c, 1, 0x04, 0x00120000 },
{ 0x419a10, 1, 0x04, 0x00000000 },
{ 0x419a14, 1, 0x04, 0x00002200 },
{ 0x419a1c, 1, 0x04, 0x0000c000 },
{ 0x419a20, 1, 0x04, 0x20008a00 },
{ 0x419a30, 1, 0x04, 0x00000001 },
{ 0x419a3c, 1, 0x04, 0x00000002 },
{ 0x419ac4, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000001a },
{ 0x419c04, 1, 0x04, 0x80000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
{ 0x419c20, 1, 0x04, 0x00000000 },
{ 0x419c24, 1, 0x04, 0x00084210 },
{ 0x419c28, 1, 0x04, 0x3efbefbe },
{ 0x419c2c, 1, 0x04, 0x00000000 },
{ 0x419c34, 1, 0x04, 0x01ff1ff3 },
{ 0x419c3c, 1, 0x04, 0x00001919 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_l1c_0[] = {
{ 0x419c84, 1, 0x04, 0x00000020 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00001c02 },
{ 0x419e44, 1, 0x04, 0x00d3eff2 },
{ 0x419e48, 1, 0x04, 0x00000000 },
{ 0x419e4c, 1, 0x04, 0x0000007f },
{ 0x419e50, 1, 0x04, 0x00000000 },
{ 0x419e60, 4, 0x04, 0x00000000 },
{ 0x419e74, 10, 0x04, 0x00000000 },
{ 0x419eac, 1, 0x04, 0x0001cf8b },
{ 0x419eb0, 1, 0x04, 0x00030300 },
{ 0x419eb8, 1, 0x04, 0x00000000 },
{ 0x419ef0, 24, 0x04, 0x00000000 },
{ 0x419f68, 2, 0x04, 0x00000000 },
{ 0x419f70, 1, 0x04, 0x00000020 },
{ 0x419f78, 1, 0x04, 0x000003eb },
{ 0x419f7c, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
gm107_grctx_pack_tpc[] = {
{ nvd7_grctx_init_pe_0 },
{ gm107_grctx_init_tex_0 },
{ gm107_grctx_init_mpc_0 },
{ gm107_grctx_init_l1c_0 },
{ gm107_grctx_init_sm_0 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x00000000 },
{ 0x41bec4, 1, 0x04, 0x01050000 },
{ 0x41bee4, 1, 0x04, 0x00000000 },
{ 0x41bef0, 1, 0x04, 0x000003ff },
{ 0x41bef4, 2, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
gm107_grctx_init_wwdx_0[] = {
{ 0x41bf00, 1, 0x04, 0x0a418820 },
{ 0x41bf04, 1, 0x04, 0x062080e6 },
{ 0x41bf08, 1, 0x04, 0x020398a4 },
{ 0x41bf0c, 1, 0x04, 0x0e629062 },
{ 0x41bf10, 1, 0x04, 0x0a418820 },
{ 0x41bf14, 1, 0x04, 0x000000e6 },
{ 0x41bfd0, 1, 0x04, 0x00900103 },
{ 0x41bfe0, 1, 0x04, 0x80000000 },
{ 0x41bfe4, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
gm107_grctx_pack_ppc[] = {
{ nve4_grctx_init_pes_0 },
{ gm107_grctx_init_cbm_0 },
{ gm107_grctx_init_wwdx_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
static void
gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x200000, 0x1000, NV_MEM_ACCESS_RW);
mmio_list(0x40800c, 0x00000000, 8, 1);
mmio_list(0x408010, 0x80000000, 0, 0);
mmio_list(0x419004, 0x00000000, 8, 1);
mmio_list(0x419008, 0x00000000, 0, 0);
mmio_list(0x4064cc, 0x80000000, 0, 0);
mmio_list(0x418e30, 0x80000000, 0, 0);
mmio_list(0x408004, 0x00000000, 8, 0);
mmio_list(0x408008, 0x80000030, 0, 0);
mmio_list(0x418e24, 0x00000000, 8, 0);
mmio_list(0x418e28, 0x80000030, 0, 0);
mmio_list(0x4064c8, 0x018002c0, 0, 0);
mmio_list(0x418810, 0x80000000, 12, 2);
mmio_list(0x419848, 0x10000000, 12, 2);
mmio_list(0x419c2c, 0x10000000, 12, 2);
mmio_list(0x405830, 0x0aa01000, 0, 0);
mmio_list(0x4064c4, 0x0400ffff, 0, 0);
/*XXX*/
mmio_list(0x5030c0, 0x00001540, 0, 0);
mmio_list(0x5030f4, 0x00000000, 0, 0);
mmio_list(0x5030e4, 0x00002000, 0, 0);
mmio_list(0x5030f8, 0x00003fc0, 0, 0);
mmio_list(0x418ea0, 0x07151540, 0, 0);
mmio_list(0x5032c0, 0x00001540, 0, 0);
mmio_list(0x5032f4, 0x00001fe0, 0, 0);
mmio_list(0x5032e4, 0x00002000, 0, 0);
mmio_list(0x5032f8, 0x00006fc0, 0, 0);
mmio_list(0x418ea4, 0x07151540, 0, 0);
}
static void
gm107_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
{
int gpc, tpc, id;
for (tpc = 0, id = 0; tpc < 4; tpc++) {
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
if (tpc < priv->tpc_nr[gpc]) {
nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id);
nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id);
id++;
}
nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
}
}
}
static void
gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
int i;
nvc0_graph_mmio(priv, oclass->hub);
nvc0_graph_mmio(priv, oclass->gpc);
nvc0_graph_mmio(priv, oclass->zcull);
nvc0_graph_mmio(priv, oclass->tpc);
nvc0_graph_mmio(priv, oclass->ppc);
nv_wr32(priv, 0x404154, 0x00000000);
oclass->mods(priv, info);
oclass->unkn(priv);
gm107_grctx_generate_tpcid(priv);
nvc0_grctx_generate_r406028(priv);
nve4_grctx_generate_r418bb8(priv);
nvc0_grctx_generate_r406800(priv);
nv_wr32(priv, 0x4064d0, 0x00000001);
for (i = 1; i < 8; i++)
nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
nv_wr32(priv, 0x406500, 0x00000001);
nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr);
if (priv->gpc_nr == 1) {
nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]);
nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]);
} else {
nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr);
nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
}
nvc0_graph_icmd(priv, oclass->icmd);
nv_wr32(priv, 0x404154, 0x00000400);
nvc0_graph_mthd(priv, oclass->mthd);
nv_mask(priv, 0x419e00, 0x00808080, 0x00808080);
nv_mask(priv, 0x419ccc, 0x80000000, 0x80000000);
nv_mask(priv, 0x419f80, 0x80000000, 0x80000000);
nv_mask(priv, 0x419f88, 0x80000000, 0x80000000);
}
struct nouveau_oclass *
gm107_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0x08),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = gm107_grctx_generate_main,
.mods = gm107_grctx_generate_mods,
.unkn = nve4_grctx_generate_unkn,
.hub = gm107_grctx_pack_hub,
.gpc = gm107_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = gm107_grctx_pack_tpc,
.ppc = gm107_grctx_pack_ppc,
.icmd = gm107_grctx_pack_icmd,
.mthd = gm107_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,597 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
nv108_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
{ 0x00003d, 1, 0x01, 0x00000001 },
{ 0x0000e8, 8, 0x01, 0x00000400 },
{ 0x000078, 8, 0x01, 0x00000300 },
{ 0x000050, 1, 0x01, 0x00000011 },
{ 0x000058, 8, 0x01, 0x00000008 },
{ 0x000208, 8, 0x01, 0x00000001 },
{ 0x000081, 1, 0x01, 0x00000001 },
{ 0x000085, 1, 0x01, 0x00000004 },
{ 0x000088, 1, 0x01, 0x00000400 },
{ 0x000090, 1, 0x01, 0x00000300 },
{ 0x000098, 1, 0x01, 0x00001001 },
{ 0x0000e3, 1, 0x01, 0x00000001 },
{ 0x0000da, 1, 0x01, 0x00000001 },
{ 0x0000f8, 1, 0x01, 0x00000003 },
{ 0x0000fa, 1, 0x01, 0x00000001 },
{ 0x00009f, 4, 0x01, 0x0000ffff },
{ 0x0000b1, 1, 0x01, 0x00000001 },
{ 0x0000ad, 1, 0x01, 0x0000013e },
{ 0x0000e1, 1, 0x01, 0x00000010 },
{ 0x000290, 16, 0x01, 0x00000000 },
{ 0x0003b0, 16, 0x01, 0x00000000 },
{ 0x0002a0, 16, 0x01, 0x00000000 },
{ 0x000420, 16, 0x01, 0x00000000 },
{ 0x0002b0, 16, 0x01, 0x00000000 },
{ 0x000430, 16, 0x01, 0x00000000 },
{ 0x0002c0, 16, 0x01, 0x00000000 },
{ 0x0004d0, 16, 0x01, 0x00000000 },
{ 0x000720, 16, 0x01, 0x00000000 },
{ 0x0008c0, 16, 0x01, 0x00000000 },
{ 0x000890, 16, 0x01, 0x00000000 },
{ 0x0008e0, 16, 0x01, 0x00000000 },
{ 0x0008a0, 16, 0x01, 0x00000000 },
{ 0x0008f0, 16, 0x01, 0x00000000 },
{ 0x00094c, 1, 0x01, 0x000000ff },
{ 0x00094d, 1, 0x01, 0xffffffff },
{ 0x00094e, 1, 0x01, 0x00000002 },
{ 0x0002ec, 1, 0x01, 0x00000001 },
{ 0x0002f2, 2, 0x01, 0x00000001 },
{ 0x0002f5, 1, 0x01, 0x00000001 },
{ 0x0002f7, 1, 0x01, 0x00000001 },
{ 0x000303, 1, 0x01, 0x00000001 },
{ 0x0002e6, 1, 0x01, 0x00000001 },
{ 0x000466, 1, 0x01, 0x00000052 },
{ 0x000301, 1, 0x01, 0x3f800000 },
{ 0x000304, 1, 0x01, 0x30201000 },
{ 0x000305, 1, 0x01, 0x70605040 },
{ 0x000306, 1, 0x01, 0xb8a89888 },
{ 0x000307, 1, 0x01, 0xf8e8d8c8 },
{ 0x00030a, 1, 0x01, 0x00ffff00 },
{ 0x00030b, 1, 0x01, 0x0000001a },
{ 0x00030c, 1, 0x01, 0x00000001 },
{ 0x000318, 1, 0x01, 0x00000001 },
{ 0x000340, 1, 0x01, 0x00000000 },
{ 0x000375, 1, 0x01, 0x00000001 },
{ 0x00037d, 1, 0x01, 0x00000006 },
{ 0x0003a0, 1, 0x01, 0x00000002 },
{ 0x0003aa, 1, 0x01, 0x00000001 },
{ 0x0003a9, 1, 0x01, 0x00000001 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000383, 1, 0x01, 0x00000011 },
{ 0x000360, 1, 0x01, 0x00000040 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00000fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x000fffff },
{ 0x00037a, 1, 0x01, 0x00000012 },
{ 0x000619, 1, 0x01, 0x00000003 },
{ 0x000811, 1, 0x01, 0x00000003 },
{ 0x000812, 1, 0x01, 0x00000004 },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000815, 1, 0x01, 0x0000000b },
{ 0x000800, 6, 0x01, 0x00000001 },
{ 0x000632, 1, 0x01, 0x00000001 },
{ 0x000633, 1, 0x01, 0x00000002 },
{ 0x000634, 1, 0x01, 0x00000003 },
{ 0x000635, 1, 0x01, 0x00000004 },
{ 0x000654, 1, 0x01, 0x3f800000 },
{ 0x000657, 1, 0x01, 0x3f800000 },
{ 0x000655, 2, 0x01, 0x3f800000 },
{ 0x0006cd, 1, 0x01, 0x3f800000 },
{ 0x0007f5, 1, 0x01, 0x3f800000 },
{ 0x0007dc, 1, 0x01, 0x39291909 },
{ 0x0007dd, 1, 0x01, 0x79695949 },
{ 0x0007de, 1, 0x01, 0xb9a99989 },
{ 0x0007df, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007e8, 1, 0x01, 0x00003210 },
{ 0x0007e9, 1, 0x01, 0x00007654 },
{ 0x0007ea, 1, 0x01, 0x00000098 },
{ 0x0007ec, 1, 0x01, 0x39291909 },
{ 0x0007ed, 1, 0x01, 0x79695949 },
{ 0x0007ee, 1, 0x01, 0xb9a99989 },
{ 0x0007ef, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007f0, 1, 0x01, 0x00003210 },
{ 0x0007f1, 1, 0x01, 0x00007654 },
{ 0x0007f2, 1, 0x01, 0x00000098 },
{ 0x0005a5, 1, 0x01, 0x00000001 },
{ 0x000980, 128, 0x01, 0x00000000 },
{ 0x000468, 1, 0x01, 0x00000004 },
{ 0x00046c, 1, 0x01, 0x00000001 },
{ 0x000470, 96, 0x01, 0x00000000 },
{ 0x000510, 16, 0x01, 0x3f800000 },
{ 0x000520, 1, 0x01, 0x000002b6 },
{ 0x000529, 1, 0x01, 0x00000001 },
{ 0x000530, 16, 0x01, 0xffff0000 },
{ 0x000585, 1, 0x01, 0x0000003f },
{ 0x000576, 1, 0x01, 0x00000003 },
{ 0x00057b, 1, 0x01, 0x00000059 },
{ 0x000586, 1, 0x01, 0x00000040 },
{ 0x000582, 2, 0x01, 0x00000080 },
{ 0x0005c2, 1, 0x01, 0x00000001 },
{ 0x000638, 2, 0x01, 0x00000001 },
{ 0x00063a, 1, 0x01, 0x00000002 },
{ 0x00063b, 2, 0x01, 0x00000001 },
{ 0x00063d, 1, 0x01, 0x00000002 },
{ 0x00063e, 1, 0x01, 0x00000001 },
{ 0x0008b8, 8, 0x01, 0x00000001 },
{ 0x000900, 8, 0x01, 0x00000001 },
{ 0x000908, 8, 0x01, 0x00000002 },
{ 0x000910, 16, 0x01, 0x00000001 },
{ 0x000920, 8, 0x01, 0x00000002 },
{ 0x000928, 8, 0x01, 0x00000001 },
{ 0x000662, 1, 0x01, 0x00000001 },
{ 0x000648, 9, 0x01, 0x00000001 },
{ 0x000658, 1, 0x01, 0x0000000f },
{ 0x0007ff, 1, 0x01, 0x0000000a },
{ 0x00066a, 1, 0x01, 0x40000000 },
{ 0x00066b, 1, 0x01, 0x10000000 },
{ 0x00066c, 2, 0x01, 0xffff0000 },
{ 0x0007af, 2, 0x01, 0x00000008 },
{ 0x0007f6, 1, 0x01, 0x00000001 },
{ 0x00080b, 1, 0x01, 0x00000002 },
{ 0x0006b2, 1, 0x01, 0x00000055 },
{ 0x0007ad, 1, 0x01, 0x00000003 },
{ 0x000937, 1, 0x01, 0x00000001 },
{ 0x000971, 1, 0x01, 0x00000008 },
{ 0x000972, 1, 0x01, 0x00000040 },
{ 0x000973, 1, 0x01, 0x0000012c },
{ 0x00097c, 1, 0x01, 0x00000040 },
{ 0x000979, 1, 0x01, 0x00000003 },
{ 0x000975, 1, 0x01, 0x00000020 },
{ 0x000976, 1, 0x01, 0x00000001 },
{ 0x000977, 1, 0x01, 0x00000020 },
{ 0x000978, 1, 0x01, 0x00000001 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095e, 1, 0x01, 0x20164010 },
{ 0x00095f, 1, 0x01, 0x00000020 },
{ 0x000a0d, 1, 0x01, 0x00000006 },
{ 0x00097d, 1, 0x01, 0x00000020 },
{ 0x000683, 1, 0x01, 0x00000006 },
{ 0x000685, 1, 0x01, 0x003fffff },
{ 0x000687, 1, 0x01, 0x003fffff },
{ 0x0006a0, 1, 0x01, 0x00000005 },
{ 0x000840, 1, 0x01, 0x00400008 },
{ 0x000841, 1, 0x01, 0x08000080 },
{ 0x000842, 1, 0x01, 0x00400008 },
{ 0x000843, 1, 0x01, 0x08000080 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ab, 1, 0x01, 0x00000002 },
{ 0x0006ac, 1, 0x01, 0x00000080 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x0006bb, 1, 0x01, 0x000000cf },
{ 0x0006ce, 1, 0x01, 0x2a712488 },
{ 0x000739, 1, 0x01, 0x4085c000 },
{ 0x00073a, 1, 0x01, 0x00000080 },
{ 0x000786, 1, 0x01, 0x80000100 },
{ 0x00073c, 1, 0x01, 0x00010100 },
{ 0x00073d, 1, 0x01, 0x02800000 },
{ 0x000787, 1, 0x01, 0x000000cf },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x000836, 1, 0x01, 0x00000001 },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x000a04, 1, 0x01, 0x000000ff },
{ 0x000a0b, 1, 0x01, 0x00000040 },
{ 0x00097f, 1, 0x01, 0x00000100 },
{ 0x000a02, 1, 0x01, 0x00000001 },
{ 0x000809, 1, 0x01, 0x00000007 },
{ 0x00c221, 1, 0x01, 0x00000040 },
{ 0x00c1b0, 8, 0x01, 0x0000000f },
{ 0x00c1b8, 1, 0x01, 0x0fac6881 },
{ 0x00c1b9, 1, 0x01, 0x00fac688 },
{ 0x00c401, 1, 0x01, 0x00000001 },
{ 0x00c402, 1, 0x01, 0x00010001 },
{ 0x00c403, 2, 0x01, 0x00000001 },
{ 0x00c40e, 1, 0x01, 0x00000020 },
{ 0x00c500, 1, 0x01, 0x00000003 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000002 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000008 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00000fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x000fffff },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x000a04, 1, 0x01, 0x000000ff },
{ 0x000a0b, 1, 0x01, 0x00000040 },
{ 0x00097f, 1, 0x01, 0x00000100 },
{ 0x000a02, 1, 0x01, 0x00000001 },
{ 0x000809, 1, 0x01, 0x00000007 },
{ 0x00c221, 1, 0x01, 0x00000040 },
{ 0x00c401, 1, 0x01, 0x00000001 },
{ 0x00c402, 1, 0x01, 0x00010001 },
{ 0x00c403, 2, 0x01, 0x00000001 },
{ 0x00c40e, 1, 0x01, 0x00000020 },
{ 0x00c500, 1, 0x01, 0x00000003 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000001 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
nv108_grctx_pack_icmd[] = {
{ nv108_grctx_init_icmd_0 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_fe_0[] = {
{ 0x404004, 8, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
{ 0x404028, 8, 0x04, 0x00000000 },
{ 0x4040a8, 8, 0x04, 0x00000000 },
{ 0x4040c8, 1, 0x04, 0xf800008f },
{ 0x4040d0, 6, 0x04, 0x00000000 },
{ 0x4040e8, 1, 0x04, 0x00001000 },
{ 0x4040f8, 1, 0x04, 0x00000000 },
{ 0x404100, 10, 0x04, 0x00000000 },
{ 0x404130, 2, 0x04, 0x00000000 },
{ 0x404138, 1, 0x04, 0x20000040 },
{ 0x404150, 1, 0x04, 0x0000002e },
{ 0x404154, 1, 0x04, 0x00000400 },
{ 0x404158, 1, 0x04, 0x00000200 },
{ 0x404164, 1, 0x04, 0x00000055 },
{ 0x40417c, 2, 0x04, 0x00000000 },
{ 0x404194, 1, 0x04, 0x01000700 },
{ 0x4041a0, 4, 0x04, 0x00000000 },
{ 0x404200, 1, 0x04, 0x0000a197 },
{ 0x404204, 1, 0x04, 0x0000a1c0 },
{ 0x404208, 1, 0x04, 0x0000a140 },
{ 0x40420c, 1, 0x04, 0x0000902d },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180648 },
{ 0x405834, 1, 0x04, 0x08000000 },
{ 0x405838, 1, 0x04, 0x00000000 },
{ 0x405854, 1, 0x04, 0x00000000 },
{ 0x405870, 4, 0x04, 0x00000001 },
{ 0x405a00, 2, 0x04, 0x00000000 },
{ 0x405a18, 1, 0x04, 0x00000000 },
{ 0x405a1c, 1, 0x04, 0x000000ff },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x034103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
{ 0x4064ac, 1, 0x04, 0x00003fff },
{ 0x4064b0, 3, 0x04, 0x00000000 },
{ 0x4064c0, 1, 0x04, 0x802000f0 },
{ 0x4064c4, 1, 0x04, 0x0192ffff },
{ 0x4064c8, 1, 0x04, 0x00c20200 },
{ 0x4064cc, 9, 0x04, 0x00000000 },
{ 0x4064fc, 1, 0x04, 0x0000022a },
{}
};
const struct nvc0_graph_init
nv108_grctx_init_rstr2d_0[] = {
{ 0x407804, 1, 0x04, 0x00000063 },
{ 0x40780c, 1, 0x04, 0x0a418820 },
{ 0x407810, 1, 0x04, 0x062080e6 },
{ 0x407814, 1, 0x04, 0x020398a4 },
{ 0x407818, 1, 0x04, 0x0e629062 },
{ 0x40781c, 1, 0x04, 0x0a418820 },
{ 0x407820, 1, 0x04, 0x000000e6 },
{ 0x4078bc, 1, 0x04, 0x00000103 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x32802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
{ 0x408840, 1, 0x04, 0x0000000b },
{ 0x408900, 1, 0x04, 0xb080b801 },
{ 0x408904, 1, 0x04, 0x62000001 },
{ 0x408908, 1, 0x04, 0x02c8102f },
{ 0x408980, 1, 0x04, 0x0000011d },
{}
};
static const struct nvc0_graph_pack
nv108_grctx_pack_hub[] = {
{ nvc0_grctx_init_main_0 },
{ nv108_grctx_init_fe_0 },
{ nvf0_grctx_init_pri_0 },
{ nve4_grctx_init_memfmt_0 },
{ nv108_grctx_init_ds_0 },
{ nvf0_grctx_init_cwd_0 },
{ nv108_grctx_init_pd_0 },
{ nv108_grctx_init_rstr2d_0 },
{ nve4_grctx_init_scc_0 },
{ nv108_grctx_init_be_0 },
{}
};
const struct nvc0_graph_init
nv108_grctx_init_prop_0[] = {
{ 0x418400, 1, 0x04, 0x38005e00 },
{ 0x418404, 1, 0x04, 0x71e0ffff },
{ 0x41840c, 1, 0x04, 0x00001008 },
{ 0x418410, 1, 0x04, 0x0fff0fff },
{ 0x418414, 1, 0x04, 0x02200fff },
{ 0x418450, 6, 0x04, 0x00000000 },
{ 0x418468, 1, 0x04, 0x00000001 },
{ 0x41846c, 2, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000007f },
{ 0x418684, 1, 0x04, 0x0000001f },
{ 0x418700, 1, 0x04, 0x00000002 },
{ 0x418704, 2, 0x04, 0x00000080 },
{ 0x41870c, 2, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006863a },
{ 0x418808, 1, 0x04, 0x00000000 },
{ 0x41880c, 1, 0x04, 0x00000030 },
{ 0x418810, 1, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00000044 },
{ 0x418830, 1, 0x04, 0x10000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x20100058 },
{}
};
const struct nvc0_graph_init
nv108_grctx_init_crstr_0[] = {
{ 0x418b00, 1, 0x04, 0x0000001e },
{ 0x418b08, 1, 0x04, 0x0a418820 },
{ 0x418b0c, 1, 0x04, 0x062080e6 },
{ 0x418b10, 1, 0x04, 0x020398a4 },
{ 0x418b14, 1, 0x04, 0x0e629062 },
{ 0x418b18, 1, 0x04, 0x0a418820 },
{ 0x418b1c, 1, 0x04, 0x000000e6 },
{ 0x418bb8, 1, 0x04, 0x00000103 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_gpm_0[] = {
{ 0x418c08, 1, 0x04, 0x00000001 },
{ 0x418c10, 8, 0x04, 0x00000000 },
{ 0x418c40, 1, 0x04, 0xffffffff },
{ 0x418c6c, 1, 0x04, 0x00000001 },
{ 0x418c80, 1, 0x04, 0x2020000c },
{ 0x418c8c, 1, 0x04, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
nv108_grctx_pack_gpc[] = {
{ nvc0_grctx_init_gpc_unk_0 },
{ nv108_grctx_init_prop_0 },
{ nv108_grctx_init_gpc_unk_1 },
{ nv108_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nv108_grctx_init_crstr_0 },
{ nv108_grctx_init_gpm_0 },
{ nvf0_grctx_init_gpc_unk_2 },
{ nvc0_grctx_init_gcc_0 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000100f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000421 },
{ 0x419a0c, 1, 0x04, 0x00120000 },
{ 0x419a10, 1, 0x04, 0x00000000 },
{ 0x419a14, 1, 0x04, 0x00000200 },
{ 0x419a1c, 1, 0x04, 0x0000c000 },
{ 0x419a20, 1, 0x04, 0x00000800 },
{ 0x419a30, 1, 0x04, 0x00000001 },
{ 0x419ac4, 1, 0x04, 0x0037f440 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_sm_0[] = {
{ 0x419e04, 1, 0x04, 0x00000000 },
{ 0x419e08, 1, 0x04, 0x0000001d },
{ 0x419e0c, 1, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00001c02 },
{ 0x419e44, 1, 0x04, 0x0013eff2 },
{ 0x419e48, 1, 0x04, 0x00000000 },
{ 0x419e4c, 1, 0x04, 0x0000007f },
{ 0x419e50, 2, 0x04, 0x00000000 },
{ 0x419e58, 1, 0x04, 0x00000001 },
{ 0x419e5c, 3, 0x04, 0x00000000 },
{ 0x419e68, 1, 0x04, 0x00000002 },
{ 0x419e6c, 12, 0x04, 0x00000000 },
{ 0x419eac, 1, 0x04, 0x00001f8f },
{ 0x419eb0, 1, 0x04, 0x0db00d2f },
{ 0x419eb8, 1, 0x04, 0x00000000 },
{ 0x419ec8, 1, 0x04, 0x0001304f },
{ 0x419f30, 4, 0x04, 0x00000000 },
{ 0x419f40, 1, 0x04, 0x00000018 },
{ 0x419f44, 3, 0x04, 0x00000000 },
{ 0x419f58, 1, 0x04, 0x00000020 },
{ 0x419f70, 1, 0x04, 0x00000000 },
{ 0x419f78, 1, 0x04, 0x000001eb },
{ 0x419f7c, 1, 0x04, 0x00000404 },
{}
};
static const struct nvc0_graph_pack
nv108_grctx_pack_tpc[] = {
{ nvd7_grctx_init_pe_0 },
{ nv108_grctx_init_tex_0 },
{ nvf0_grctx_init_mpc_0 },
{ nvf0_grctx_init_l1c_0 },
{ nv108_grctx_init_sm_0 },
{}
};
static const struct nvc0_graph_init
nv108_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x10000000 },
{ 0x41bec4, 1, 0x04, 0x00037f7f },
{ 0x41bee4, 1, 0x04, 0x00000000 },
{ 0x41bef0, 1, 0x04, 0x000003ff },
{}
};
static const struct nvc0_graph_pack
nv108_grctx_pack_ppc[] = {
{ nve4_grctx_init_pes_0 },
{ nv108_grctx_init_cbm_0 },
{ nvd7_grctx_init_wwdx_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
static void
nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
u32 magic[GPC_MAX][2];
u32 offset;
int gpc;
mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
mmio_list(0x40800c, 0x00000000, 8, 1);
mmio_list(0x408010, 0x80000000, 0, 0);
mmio_list(0x419004, 0x00000000, 8, 1);
mmio_list(0x419008, 0x00000000, 0, 0);
mmio_list(0x408004, 0x00000000, 8, 0);
mmio_list(0x408008, 0x80000030, 0, 0);
mmio_list(0x418808, 0x00000000, 8, 0);
mmio_list(0x41880c, 0x80000030, 0, 0);
mmio_list(0x418810, 0x80000000, 12, 2);
mmio_list(0x419848, 0x10000000, 12, 2);
mmio_list(0x405830, 0x02180648, 0, 0);
mmio_list(0x4064c4, 0x0192ffff, 0, 0);
for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
u16 magic1 = 0x0648 * priv->tpc_nr[gpc];
magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset;
magic[gpc][1] = 0x00000000 | (magic1 << 16);
offset += 0x0324 * priv->tpc_nr[gpc];
}
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
offset += 0x07ff * priv->tpc_nr[gpc];
}
mmio_list(0x17e91c, 0x0b040a0b, 0, 0);
mmio_list(0x17e920, 0x00090d08, 0, 0);
}
struct nouveau_oclass *
nv108_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0x08),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nve4_grctx_generate_main,
.mods = nv108_grctx_generate_mods,
.unkn = nve4_grctx_generate_unkn,
.hub = nv108_grctx_pack_hub,
.gpc = nv108_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nv108_grctx_pack_tpc,
.ppc = nv108_grctx_pack_ppc,
.icmd = nv108_grctx_pack_icmd,
.mthd = nvf0_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,695 @@
/*
* Copyright 2009 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/gpuobj.h>
/* NVIDIA context programs handle a number of other conditions which are
* not implemented in our versions. It's not clear why NVIDIA context
* programs have this code, nor whether it's strictly necessary for
* correct operation. We'll implement additional handling if/when we
* discover it's necessary.
*
* - On context save, NVIDIA set 0x400314 bit 0 to 1 if the "3D state"
* flag is set, this gets saved into the context.
* - On context save, the context program for all cards load nsource
* into a flag register and check for ILLEGAL_MTHD. If it's set,
* opcode 0x60000d is called before resuming normal operation.
* - Some context programs check more conditions than the above. NV44
* checks: ((nsource & 0x0857) || (0x400718 & 0x0100) || (intr & 0x0001))
* and calls 0x60000d before resuming normal operation.
* - At the very beginning of NVIDIA's context programs, flag 9 is checked
* and if true 0x800001 is called with count=0, pos=0, the flag is cleared
* and then the ctxprog is aborted. It looks like a complicated NOP,
* its purpose is unknown.
* - In the section of code that loads the per-vs state, NVIDIA check
* flag 10. If it's set, they only transfer the small 0x300 byte block
* of state + the state for a single vs as opposed to the state for
* all vs units. It doesn't seem likely that it'll occur in normal
* operation, especially seeing as it appears NVIDIA may have screwed
* up the ctxprogs for some cards and have an invalid instruction
* rather than a cp_lsr(ctx, dwords_for_1_vs_unit) instruction.
* - There's a number of places where context offset 0 (where we place
* the PRAMIN offset of the context) is loaded into either 0x408000,
* 0x408004 or 0x408008. Not sure what's up there either.
* - The ctxprogs for some cards save 0x400a00 again during the cleanup
* path for auto-loadctx.
*/
#define CP_FLAG_CLEAR 0
#define CP_FLAG_SET 1
#define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0)
#define CP_FLAG_SWAP_DIRECTION_LOAD 0
#define CP_FLAG_SWAP_DIRECTION_SAVE 1
#define CP_FLAG_USER_SAVE ((0 * 32) + 5)
#define CP_FLAG_USER_SAVE_NOT_PENDING 0
#define CP_FLAG_USER_SAVE_PENDING 1
#define CP_FLAG_USER_LOAD ((0 * 32) + 6)
#define CP_FLAG_USER_LOAD_NOT_PENDING 0
#define CP_FLAG_USER_LOAD_PENDING 1
#define CP_FLAG_STATUS ((3 * 32) + 0)
#define CP_FLAG_STATUS_IDLE 0
#define CP_FLAG_STATUS_BUSY 1
#define CP_FLAG_AUTO_SAVE ((3 * 32) + 4)
#define CP_FLAG_AUTO_SAVE_NOT_PENDING 0
#define CP_FLAG_AUTO_SAVE_PENDING 1
#define CP_FLAG_AUTO_LOAD ((3 * 32) + 5)
#define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
#define CP_FLAG_AUTO_LOAD_PENDING 1
#define CP_FLAG_UNK54 ((3 * 32) + 6)
#define CP_FLAG_UNK54_CLEAR 0
#define CP_FLAG_UNK54_SET 1
#define CP_FLAG_ALWAYS ((3 * 32) + 8)
#define CP_FLAG_ALWAYS_FALSE 0
#define CP_FLAG_ALWAYS_TRUE 1
#define CP_FLAG_UNK57 ((3 * 32) + 9)
#define CP_FLAG_UNK57_CLEAR 0
#define CP_FLAG_UNK57_SET 1
#define CP_CTX 0x00100000
#define CP_CTX_COUNT 0x000fc000
#define CP_CTX_COUNT_SHIFT 14
#define CP_CTX_REG 0x00003fff
#define CP_LOAD_SR 0x00200000
#define CP_LOAD_SR_VALUE 0x000fffff
#define CP_BRA 0x00400000
#define CP_BRA_IP 0x0000ff00
#define CP_BRA_IP_SHIFT 8
#define CP_BRA_IF_CLEAR 0x00000080
#define CP_BRA_FLAG 0x0000007f
#define CP_WAIT 0x00500000
#define CP_WAIT_SET 0x00000080
#define CP_WAIT_FLAG 0x0000007f
#define CP_SET 0x00700000
#define CP_SET_1 0x00000080
#define CP_SET_FLAG 0x0000007f
#define CP_NEXT_TO_SWAP 0x00600007
#define CP_NEXT_TO_CURRENT 0x00600009
#define CP_SET_CONTEXT_POINTER 0x0060000a
#define CP_END 0x0060000e
#define CP_LOAD_MAGIC_UNK01 0x00800001 /* unknown */
#define CP_LOAD_MAGIC_NV44TCL 0x00800029 /* per-vs state (0x4497) */
#define CP_LOAD_MAGIC_NV40TCL 0x00800041 /* per-vs state (0x4097) */
#include "nv40.h"
#include "ctx.h"
/* TODO:
* - get vs count from 0x1540
*/
static int
nv40_graph_vs_count(struct nouveau_device *device)
{
switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
return 8;
case 0x40:
return 6;
case 0x41:
case 0x42:
return 5;
case 0x43:
case 0x44:
case 0x46:
case 0x4a:
return 3;
case 0x4c:
case 0x4e:
case 0x67:
default:
return 1;
}
}
enum cp_label {
cp_check_load = 1,
cp_setup_auto_load,
cp_setup_load,
cp_setup_save,
cp_swap_state,
cp_swap_state3d_3_is_save,
cp_prepare_exit,
cp_exit,
};
static void
nv40_graph_construct_general(struct nouveau_grctx *ctx)
{
struct nouveau_device *device = ctx->device;
int i;
cp_ctx(ctx, 0x4000a4, 1);
gr_def(ctx, 0x4000a4, 0x00000008);
cp_ctx(ctx, 0x400144, 58);
gr_def(ctx, 0x400144, 0x00000001);
cp_ctx(ctx, 0x400314, 1);
gr_def(ctx, 0x400314, 0x00000000);
cp_ctx(ctx, 0x400400, 10);
cp_ctx(ctx, 0x400480, 10);
cp_ctx(ctx, 0x400500, 19);
gr_def(ctx, 0x400514, 0x00040000);
gr_def(ctx, 0x400524, 0x55555555);
gr_def(ctx, 0x400528, 0x55555555);
gr_def(ctx, 0x40052c, 0x55555555);
gr_def(ctx, 0x400530, 0x55555555);
cp_ctx(ctx, 0x400560, 6);
gr_def(ctx, 0x400568, 0x0000ffff);
gr_def(ctx, 0x40056c, 0x0000ffff);
cp_ctx(ctx, 0x40057c, 5);
cp_ctx(ctx, 0x400710, 3);
gr_def(ctx, 0x400710, 0x20010001);
gr_def(ctx, 0x400714, 0x0f73ef00);
cp_ctx(ctx, 0x400724, 1);
gr_def(ctx, 0x400724, 0x02008821);
cp_ctx(ctx, 0x400770, 3);
if (device->chipset == 0x40) {
cp_ctx(ctx, 0x400814, 4);
cp_ctx(ctx, 0x400828, 5);
cp_ctx(ctx, 0x400840, 5);
gr_def(ctx, 0x400850, 0x00000040);
cp_ctx(ctx, 0x400858, 4);
gr_def(ctx, 0x400858, 0x00000040);
gr_def(ctx, 0x40085c, 0x00000040);
gr_def(ctx, 0x400864, 0x80000000);
cp_ctx(ctx, 0x40086c, 9);
gr_def(ctx, 0x40086c, 0x80000000);
gr_def(ctx, 0x400870, 0x80000000);
gr_def(ctx, 0x400874, 0x80000000);
gr_def(ctx, 0x400878, 0x80000000);
gr_def(ctx, 0x400888, 0x00000040);
gr_def(ctx, 0x40088c, 0x80000000);
cp_ctx(ctx, 0x4009c0, 8);
gr_def(ctx, 0x4009cc, 0x80000000);
gr_def(ctx, 0x4009dc, 0x80000000);
} else {
cp_ctx(ctx, 0x400840, 20);
if (nv44_graph_class(ctx->device)) {
for (i = 0; i < 8; i++)
gr_def(ctx, 0x400860 + (i * 4), 0x00000001);
}
gr_def(ctx, 0x400880, 0x00000040);
gr_def(ctx, 0x400884, 0x00000040);
gr_def(ctx, 0x400888, 0x00000040);
cp_ctx(ctx, 0x400894, 11);
gr_def(ctx, 0x400894, 0x00000040);
if (!nv44_graph_class(ctx->device)) {
for (i = 0; i < 8; i++)
gr_def(ctx, 0x4008a0 + (i * 4), 0x80000000);
}
cp_ctx(ctx, 0x4008e0, 2);
cp_ctx(ctx, 0x4008f8, 2);
if (device->chipset == 0x4c ||
(device->chipset & 0xf0) == 0x60)
cp_ctx(ctx, 0x4009f8, 1);
}
cp_ctx(ctx, 0x400a00, 73);
gr_def(ctx, 0x400b0c, 0x0b0b0b0c);
cp_ctx(ctx, 0x401000, 4);
cp_ctx(ctx, 0x405004, 1);
switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
cp_ctx(ctx, 0x403448, 1);
gr_def(ctx, 0x403448, 0x00001010);
break;
default:
cp_ctx(ctx, 0x403440, 1);
switch (device->chipset) {
case 0x40:
gr_def(ctx, 0x403440, 0x00000010);
break;
case 0x44:
case 0x46:
case 0x4a:
gr_def(ctx, 0x403440, 0x00003010);
break;
case 0x41:
case 0x42:
case 0x43:
case 0x4c:
case 0x4e:
case 0x67:
default:
gr_def(ctx, 0x403440, 0x00001010);
break;
}
break;
}
}
static void
nv40_graph_construct_state3d(struct nouveau_grctx *ctx)
{
struct nouveau_device *device = ctx->device;
int i;
if (device->chipset == 0x40) {
cp_ctx(ctx, 0x401880, 51);
gr_def(ctx, 0x401940, 0x00000100);
} else
if (device->chipset == 0x46 || device->chipset == 0x47 ||
device->chipset == 0x49 || device->chipset == 0x4b) {
cp_ctx(ctx, 0x401880, 32);
for (i = 0; i < 16; i++)
gr_def(ctx, 0x401880 + (i * 4), 0x00000111);
if (device->chipset == 0x46)
cp_ctx(ctx, 0x401900, 16);
cp_ctx(ctx, 0x401940, 3);
}
cp_ctx(ctx, 0x40194c, 18);
gr_def(ctx, 0x401954, 0x00000111);
gr_def(ctx, 0x401958, 0x00080060);
gr_def(ctx, 0x401974, 0x00000080);
gr_def(ctx, 0x401978, 0xffff0000);
gr_def(ctx, 0x40197c, 0x00000001);
gr_def(ctx, 0x401990, 0x46400000);
if (device->chipset == 0x40) {
cp_ctx(ctx, 0x4019a0, 2);
cp_ctx(ctx, 0x4019ac, 5);
} else {
cp_ctx(ctx, 0x4019a0, 1);
cp_ctx(ctx, 0x4019b4, 3);
}
gr_def(ctx, 0x4019bc, 0xffff0000);
switch (device->chipset) {
case 0x46:
case 0x47:
case 0x49:
case 0x4b:
cp_ctx(ctx, 0x4019c0, 18);
for (i = 0; i < 16; i++)
gr_def(ctx, 0x4019c0 + (i * 4), 0x88888888);
break;
}
cp_ctx(ctx, 0x401a08, 8);
gr_def(ctx, 0x401a10, 0x0fff0000);
gr_def(ctx, 0x401a14, 0x0fff0000);
gr_def(ctx, 0x401a1c, 0x00011100);
cp_ctx(ctx, 0x401a2c, 4);
cp_ctx(ctx, 0x401a44, 26);
for (i = 0; i < 16; i++)
gr_def(ctx, 0x401a44 + (i * 4), 0x07ff0000);
gr_def(ctx, 0x401a8c, 0x4b7fffff);
if (device->chipset == 0x40) {
cp_ctx(ctx, 0x401ab8, 3);
} else {
cp_ctx(ctx, 0x401ab8, 1);
cp_ctx(ctx, 0x401ac0, 1);
}
cp_ctx(ctx, 0x401ad0, 8);
gr_def(ctx, 0x401ad0, 0x30201000);
gr_def(ctx, 0x401ad4, 0x70605040);
gr_def(ctx, 0x401ad8, 0xb8a89888);
gr_def(ctx, 0x401adc, 0xf8e8d8c8);
cp_ctx(ctx, 0x401b10, device->chipset == 0x40 ? 2 : 1);
gr_def(ctx, 0x401b10, 0x40100000);
cp_ctx(ctx, 0x401b18, device->chipset == 0x40 ? 6 : 5);
gr_def(ctx, 0x401b28, device->chipset == 0x40 ?
0x00000004 : 0x00000000);
cp_ctx(ctx, 0x401b30, 25);
gr_def(ctx, 0x401b34, 0x0000ffff);
gr_def(ctx, 0x401b68, 0x435185d6);
gr_def(ctx, 0x401b6c, 0x2155b699);
gr_def(ctx, 0x401b70, 0xfedcba98);
gr_def(ctx, 0x401b74, 0x00000098);
gr_def(ctx, 0x401b84, 0xffffffff);
gr_def(ctx, 0x401b88, 0x00ff7000);
gr_def(ctx, 0x401b8c, 0x0000ffff);
if (device->chipset != 0x44 && device->chipset != 0x4a &&
device->chipset != 0x4e)
cp_ctx(ctx, 0x401b94, 1);
cp_ctx(ctx, 0x401b98, 8);
gr_def(ctx, 0x401b9c, 0x00ff0000);
cp_ctx(ctx, 0x401bc0, 9);
gr_def(ctx, 0x401be0, 0x00ffff00);
cp_ctx(ctx, 0x401c00, 192);
for (i = 0; i < 16; i++) { /* fragment texture units */
gr_def(ctx, 0x401c40 + (i * 4), 0x00018488);
gr_def(ctx, 0x401c80 + (i * 4), 0x00028202);
gr_def(ctx, 0x401d00 + (i * 4), 0x0000aae4);
gr_def(ctx, 0x401d40 + (i * 4), 0x01012000);
gr_def(ctx, 0x401d80 + (i * 4), 0x00080008);
gr_def(ctx, 0x401e00 + (i * 4), 0x00100008);
}
for (i = 0; i < 4; i++) { /* vertex texture units */
gr_def(ctx, 0x401e90 + (i * 4), 0x0001bc80);
gr_def(ctx, 0x401ea0 + (i * 4), 0x00000202);
gr_def(ctx, 0x401ec0 + (i * 4), 0x00000008);
gr_def(ctx, 0x401ee0 + (i * 4), 0x00080008);
}
cp_ctx(ctx, 0x400f5c, 3);
gr_def(ctx, 0x400f5c, 0x00000002);
cp_ctx(ctx, 0x400f84, 1);
}
static void
nv40_graph_construct_state3d_2(struct nouveau_grctx *ctx)
{
struct nouveau_device *device = ctx->device;
int i;
cp_ctx(ctx, 0x402000, 1);
cp_ctx(ctx, 0x402404, device->chipset == 0x40 ? 1 : 2);
switch (device->chipset) {
case 0x40:
gr_def(ctx, 0x402404, 0x00000001);
break;
case 0x4c:
case 0x4e:
case 0x67:
gr_def(ctx, 0x402404, 0x00000020);
break;
case 0x46:
case 0x49:
case 0x4b:
gr_def(ctx, 0x402404, 0x00000421);
break;
default:
gr_def(ctx, 0x402404, 0x00000021);
}
if (device->chipset != 0x40)
gr_def(ctx, 0x402408, 0x030c30c3);
switch (device->chipset) {
case 0x44:
case 0x46:
case 0x4a:
case 0x4c:
case 0x4e:
case 0x67:
cp_ctx(ctx, 0x402440, 1);
gr_def(ctx, 0x402440, 0x00011001);
break;
default:
break;
}
cp_ctx(ctx, 0x402480, device->chipset == 0x40 ? 8 : 9);
gr_def(ctx, 0x402488, 0x3e020200);
gr_def(ctx, 0x40248c, 0x00ffffff);
switch (device->chipset) {
case 0x40:
gr_def(ctx, 0x402490, 0x60103f00);
break;
case 0x47:
gr_def(ctx, 0x402490, 0x40103f00);
break;
case 0x41:
case 0x42:
case 0x49:
case 0x4b:
gr_def(ctx, 0x402490, 0x20103f00);
break;
default:
gr_def(ctx, 0x402490, 0x0c103f00);
break;
}
gr_def(ctx, 0x40249c, device->chipset <= 0x43 ?
0x00020000 : 0x00040000);
cp_ctx(ctx, 0x402500, 31);
gr_def(ctx, 0x402530, 0x00008100);
if (device->chipset == 0x40)
cp_ctx(ctx, 0x40257c, 6);
cp_ctx(ctx, 0x402594, 16);
cp_ctx(ctx, 0x402800, 17);
gr_def(ctx, 0x402800, 0x00000001);
switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
cp_ctx(ctx, 0x402864, 1);
gr_def(ctx, 0x402864, 0x00001001);
cp_ctx(ctx, 0x402870, 3);
gr_def(ctx, 0x402878, 0x00000003);
if (device->chipset != 0x47) { /* belong at end!! */
cp_ctx(ctx, 0x402900, 1);
cp_ctx(ctx, 0x402940, 1);
cp_ctx(ctx, 0x402980, 1);
cp_ctx(ctx, 0x4029c0, 1);
cp_ctx(ctx, 0x402a00, 1);
cp_ctx(ctx, 0x402a40, 1);
cp_ctx(ctx, 0x402a80, 1);
cp_ctx(ctx, 0x402ac0, 1);
}
break;
case 0x40:
cp_ctx(ctx, 0x402844, 1);
gr_def(ctx, 0x402844, 0x00000001);
cp_ctx(ctx, 0x402850, 1);
break;
default:
cp_ctx(ctx, 0x402844, 1);
gr_def(ctx, 0x402844, 0x00001001);
cp_ctx(ctx, 0x402850, 2);
gr_def(ctx, 0x402854, 0x00000003);
break;
}
cp_ctx(ctx, 0x402c00, 4);
gr_def(ctx, 0x402c00, device->chipset == 0x40 ?
0x80800001 : 0x00888001);
switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
cp_ctx(ctx, 0x402c20, 40);
for (i = 0; i < 32; i++)
gr_def(ctx, 0x402c40 + (i * 4), 0xffffffff);
cp_ctx(ctx, 0x4030b8, 13);
gr_def(ctx, 0x4030dc, 0x00000005);
gr_def(ctx, 0x4030e8, 0x0000ffff);
break;
default:
cp_ctx(ctx, 0x402c10, 4);
if (device->chipset == 0x40)
cp_ctx(ctx, 0x402c20, 36);
else
if (device->chipset <= 0x42)
cp_ctx(ctx, 0x402c20, 24);
else
if (device->chipset <= 0x4a)
cp_ctx(ctx, 0x402c20, 16);
else
cp_ctx(ctx, 0x402c20, 8);
cp_ctx(ctx, 0x402cb0, device->chipset == 0x40 ? 12 : 13);
gr_def(ctx, 0x402cd4, 0x00000005);
if (device->chipset != 0x40)
gr_def(ctx, 0x402ce0, 0x0000ffff);
break;
}
cp_ctx(ctx, 0x403400, device->chipset == 0x40 ? 4 : 3);
cp_ctx(ctx, 0x403410, device->chipset == 0x40 ? 4 : 3);
cp_ctx(ctx, 0x403420, nv40_graph_vs_count(ctx->device));
for (i = 0; i < nv40_graph_vs_count(ctx->device); i++)
gr_def(ctx, 0x403420 + (i * 4), 0x00005555);
if (device->chipset != 0x40) {
cp_ctx(ctx, 0x403600, 1);
gr_def(ctx, 0x403600, 0x00000001);
}
cp_ctx(ctx, 0x403800, 1);
cp_ctx(ctx, 0x403c18, 1);
gr_def(ctx, 0x403c18, 0x00000001);
switch (device->chipset) {
case 0x46:
case 0x47:
case 0x49:
case 0x4b:
cp_ctx(ctx, 0x405018, 1);
gr_def(ctx, 0x405018, 0x08e00001);
cp_ctx(ctx, 0x405c24, 1);
gr_def(ctx, 0x405c24, 0x000e3000);
break;
}
if (device->chipset != 0x4e)
cp_ctx(ctx, 0x405800, 11);
cp_ctx(ctx, 0x407000, 1);
}
static void
nv40_graph_construct_state3d_3(struct nouveau_grctx *ctx)
{
int len = nv44_graph_class(ctx->device) ? 0x0084 : 0x0684;
cp_out (ctx, 0x300000);
cp_lsr (ctx, len - 4);
cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_swap_state3d_3_is_save);
cp_lsr (ctx, len);
cp_name(ctx, cp_swap_state3d_3_is_save);
cp_out (ctx, 0x800001);
ctx->ctxvals_pos += len;
}
static void
nv40_graph_construct_shader(struct nouveau_grctx *ctx)
{
struct nouveau_device *device = ctx->device;
struct nouveau_gpuobj *obj = ctx->data;
int vs, vs_nr, vs_len, vs_nr_b0, vs_nr_b1, b0_offset, b1_offset;
int offset, i;
vs_nr = nv40_graph_vs_count(ctx->device);
vs_nr_b0 = 363;
vs_nr_b1 = device->chipset == 0x40 ? 128 : 64;
if (device->chipset == 0x40) {
b0_offset = 0x2200/4; /* 33a0 */
b1_offset = 0x55a0/4; /* 1500 */
vs_len = 0x6aa0/4;
} else
if (device->chipset == 0x41 || device->chipset == 0x42) {
b0_offset = 0x2200/4; /* 2200 */
b1_offset = 0x4400/4; /* 0b00 */
vs_len = 0x4f00/4;
} else {
b0_offset = 0x1d40/4; /* 2200 */
b1_offset = 0x3f40/4; /* 0b00 : 0a40 */
vs_len = nv44_graph_class(device) ? 0x4980/4 : 0x4a40/4;
}
cp_lsr(ctx, vs_len * vs_nr + 0x300/4);
cp_out(ctx, nv44_graph_class(device) ? 0x800029 : 0x800041);
offset = ctx->ctxvals_pos;
ctx->ctxvals_pos += (0x0300/4 + (vs_nr * vs_len));
if (ctx->mode != NOUVEAU_GRCTX_VALS)
return;
offset += 0x0280/4;
for (i = 0; i < 16; i++, offset += 2)
nv_wo32(obj, offset * 4, 0x3f800000);
for (vs = 0; vs < vs_nr; vs++, offset += vs_len) {
for (i = 0; i < vs_nr_b0 * 6; i += 6)
nv_wo32(obj, (offset + b0_offset + i) * 4, 0x00000001);
for (i = 0; i < vs_nr_b1 * 4; i += 4)
nv_wo32(obj, (offset + b1_offset + i) * 4, 0x3f800000);
}
}
static void
nv40_grctx_generate(struct nouveau_grctx *ctx)
{
/* decide whether we're loading/unloading the context */
cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save);
cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save);
cp_name(ctx, cp_check_load);
cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load);
cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load);
cp_bra (ctx, ALWAYS, TRUE, cp_exit);
/* setup for context load */
cp_name(ctx, cp_setup_auto_load);
cp_wait(ctx, STATUS, IDLE);
cp_out (ctx, CP_NEXT_TO_SWAP);
cp_name(ctx, cp_setup_load);
cp_wait(ctx, STATUS, IDLE);
cp_set (ctx, SWAP_DIRECTION, LOAD);
cp_out (ctx, 0x00910880); /* ?? */
cp_out (ctx, 0x00901ffe); /* ?? */
cp_out (ctx, 0x01940000); /* ?? */
cp_lsr (ctx, 0x20);
cp_out (ctx, 0x0060000b); /* ?? */
cp_wait(ctx, UNK57, CLEAR);
cp_out (ctx, 0x0060000c); /* ?? */
cp_bra (ctx, ALWAYS, TRUE, cp_swap_state);
/* setup for context save */
cp_name(ctx, cp_setup_save);
cp_set (ctx, SWAP_DIRECTION, SAVE);
/* general PGRAPH state */
cp_name(ctx, cp_swap_state);
cp_pos (ctx, 0x00020/4);
nv40_graph_construct_general(ctx);
cp_wait(ctx, STATUS, IDLE);
/* 3D state, block 1 */
cp_bra (ctx, UNK54, CLEAR, cp_prepare_exit);
nv40_graph_construct_state3d(ctx);
cp_wait(ctx, STATUS, IDLE);
/* 3D state, block 2 */
nv40_graph_construct_state3d_2(ctx);
/* Some other block of "random" state */
nv40_graph_construct_state3d_3(ctx);
/* Per-vertex shader state */
cp_pos (ctx, ctx->ctxvals_pos);
nv40_graph_construct_shader(ctx);
/* pre-exit state updates */
cp_name(ctx, cp_prepare_exit);
cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load);
cp_bra (ctx, USER_SAVE, PENDING, cp_exit);
cp_out (ctx, CP_NEXT_TO_CURRENT);
cp_name(ctx, cp_exit);
cp_set (ctx, USER_SAVE, NOT_PENDING);
cp_set (ctx, USER_LOAD, NOT_PENDING);
cp_out (ctx, CP_END);
}
void
nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
{
nv40_grctx_generate(&(struct nouveau_grctx) {
.device = device,
.mode = NOUVEAU_GRCTX_VALS,
.data = mem,
});
}
int
nv40_grctx_init(struct nouveau_device *device, u32 *size)
{
u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
struct nouveau_grctx ctx = {
.device = device,
.mode = NOUVEAU_GRCTX_PROG,
.data = ctxprog,
.ctxprog_max = 256,
};
if (!ctxprog)
return -ENOMEM;
nv40_grctx_generate(&ctx);
nv_wr32(device, 0x400324, 0);
for (i = 0; i < ctx.ctxprog_len; i++)
nv_wr32(device, 0x400328, ctxprog[i]);
*size = ctx.ctxvals_pos * 4;
kfree(ctxprog);
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,170 @@
#ifndef __NVKM_GRCTX_NVC0_H__
#define __NVKM_GRCTX_NVC0_H__
#include "nvc0.h"
struct nvc0_grctx {
struct nvc0_graph_priv *priv;
struct nvc0_graph_data *data;
struct nvc0_graph_mmio *mmio;
int buffer_nr;
u64 buffer[4];
u64 addr;
};
struct nvc0_grctx_oclass {
struct nouveau_oclass base;
/* main context generation function */
void (*main)(struct nvc0_graph_priv *, struct nvc0_grctx *);
/* context-specific modify-on-first-load list generation function */
void (*mods)(struct nvc0_graph_priv *, struct nvc0_grctx *);
void (*unkn)(struct nvc0_graph_priv *);
/* mmio context data */
const struct nvc0_graph_pack *hub;
const struct nvc0_graph_pack *gpc;
const struct nvc0_graph_pack *zcull;
const struct nvc0_graph_pack *tpc;
const struct nvc0_graph_pack *ppc;
/* indirect context data, generated with icmds/mthds */
const struct nvc0_graph_pack *icmd;
const struct nvc0_graph_pack *mthd;
};
#define mmio_data(s,a,p) do { \
info->buffer[info->buffer_nr] = round_up(info->addr, (a)); \
info->addr = info->buffer[info->buffer_nr++] + (s); \
info->data->size = (s); \
info->data->align = (a); \
info->data->access = (p); \
info->data++; \
} while(0)
#define mmio_list(r,d,s,b) do { \
info->mmio->addr = (r); \
info->mmio->data = (d); \
info->mmio->shift = (s); \
info->mmio->buffer = (b); \
info->mmio++; \
nv_wr32(priv, (r), (d) | ((s) ? (info->buffer[(b)] >> (s)) : 0)); \
} while(0)
extern struct nouveau_oclass *nvc0_grctx_oclass;
int nvc0_grctx_generate(struct nvc0_graph_priv *);
void nvc0_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
void nvc0_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
void nvc0_grctx_generate_unkn(struct nvc0_graph_priv *);
void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *);
void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *);
void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *);
void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *);
void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *);
extern struct nouveau_oclass *nvc1_grctx_oclass;
void nvc1_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *);
extern struct nouveau_oclass *nvc4_grctx_oclass;
extern struct nouveau_oclass *nvc8_grctx_oclass;
extern struct nouveau_oclass *nvd7_grctx_oclass;
extern struct nouveau_oclass *nvd9_grctx_oclass;
extern struct nouveau_oclass *nve4_grctx_oclass;
void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
extern struct nouveau_oclass *nvf0_grctx_oclass;
extern struct nouveau_oclass *nv108_grctx_oclass;
extern struct nouveau_oclass *gm107_grctx_oclass;
/* context init value lists */
extern const struct nvc0_graph_pack nvc0_grctx_pack_icmd[];
extern const struct nvc0_graph_pack nvc0_grctx_pack_mthd[];
extern const struct nvc0_graph_init nvc0_grctx_init_902d_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_9039_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_90c0_0[];
extern const struct nvc0_graph_pack nvc0_grctx_pack_hub[];
extern const struct nvc0_graph_init nvc0_grctx_init_main_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_fe_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_pri_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_memfmt_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_rstr2d_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_scc_0[];
extern const struct nvc0_graph_pack nvc0_grctx_pack_gpc[];
extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_prop_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_1[];
extern const struct nvc0_graph_init nvc0_grctx_init_zcull_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_crstr_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_gpm_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_gcc_0[];
extern const struct nvc0_graph_pack nvc0_grctx_pack_zcull[];
extern const struct nvc0_graph_pack nvc0_grctx_pack_tpc[];
extern const struct nvc0_graph_init nvc0_grctx_init_pe_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_wwdx_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_mpc_0[];
extern const struct nvc0_graph_init nvc0_grctx_init_tpccs_0[];
extern const struct nvc0_graph_init nvc4_grctx_init_tex_0[];
extern const struct nvc0_graph_init nvc4_grctx_init_l1c_0[];
extern const struct nvc0_graph_init nvc4_grctx_init_sm_0[];
extern const struct nvc0_graph_init nvc1_grctx_init_9097_0[];
extern const struct nvc0_graph_init nvc1_grctx_init_gpm_0[];
extern const struct nvc0_graph_init nvc1_grctx_init_pe_0[];
extern const struct nvc0_graph_init nvc1_grctx_init_wwdx_0[];
extern const struct nvc0_graph_init nvc1_grctx_init_tpccs_0[];
extern const struct nvc0_graph_init nvc8_grctx_init_9197_0[];
extern const struct nvc0_graph_init nvc8_grctx_init_9297_0[];
extern const struct nvc0_graph_pack nvd9_grctx_pack_icmd[];
extern const struct nvc0_graph_pack nvd9_grctx_pack_mthd[];
extern const struct nvc0_graph_init nvd9_grctx_init_fe_0[];
extern const struct nvc0_graph_init nvd9_grctx_init_be_0[];
extern const struct nvc0_graph_init nvd9_grctx_init_prop_0[];
extern const struct nvc0_graph_init nvd9_grctx_init_gpc_unk_1[];
extern const struct nvc0_graph_init nvd9_grctx_init_crstr_0[];
extern const struct nvc0_graph_init nvd9_grctx_init_sm_0[];
extern const struct nvc0_graph_init nvd7_grctx_init_pe_0[];
extern const struct nvc0_graph_init nvd7_grctx_init_wwdx_0[];
extern const struct nvc0_graph_init nve4_grctx_init_memfmt_0[];
extern const struct nvc0_graph_init nve4_grctx_init_ds_0[];
extern const struct nvc0_graph_init nve4_grctx_init_scc_0[];
extern const struct nvc0_graph_init nve4_grctx_init_gpm_0[];
extern const struct nvc0_graph_init nve4_grctx_init_pes_0[];
extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[];
extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[];
extern const struct nvc0_graph_init nvf0_grctx_init_cwd_0[];
extern const struct nvc0_graph_init nvf0_grctx_init_gpc_unk_2[];
extern const struct nvc0_graph_init nvf0_grctx_init_mpc_0[];
extern const struct nvc0_graph_init nvf0_grctx_init_l1c_0[];
extern const struct nvc0_graph_init nv108_grctx_init_rstr2d_0[];
extern const struct nvc0_graph_init nv108_grctx_init_prop_0[];
extern const struct nvc0_graph_init nv108_grctx_init_crstr_0[];
#endif

View File

@ -0,0 +1,797 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
nvc1_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
{ 0x00003d, 1, 0x01, 0x00000001 },
{ 0x0000e8, 8, 0x01, 0x00000400 },
{ 0x000078, 8, 0x01, 0x00000300 },
{ 0x000050, 1, 0x01, 0x00000011 },
{ 0x000058, 8, 0x01, 0x00000008 },
{ 0x000208, 8, 0x01, 0x00000001 },
{ 0x000081, 1, 0x01, 0x00000001 },
{ 0x000085, 1, 0x01, 0x00000004 },
{ 0x000088, 1, 0x01, 0x00000400 },
{ 0x000090, 1, 0x01, 0x00000300 },
{ 0x000098, 1, 0x01, 0x00001001 },
{ 0x0000e3, 1, 0x01, 0x00000001 },
{ 0x0000da, 1, 0x01, 0x00000001 },
{ 0x0000f8, 1, 0x01, 0x00000003 },
{ 0x0000fa, 1, 0x01, 0x00000001 },
{ 0x00009f, 4, 0x01, 0x0000ffff },
{ 0x0000b1, 1, 0x01, 0x00000001 },
{ 0x0000b2, 40, 0x01, 0x00000000 },
{ 0x000210, 8, 0x01, 0x00000040 },
{ 0x000218, 8, 0x01, 0x0000c080 },
{ 0x0000ad, 1, 0x01, 0x0000013e },
{ 0x0000e1, 1, 0x01, 0x00000010 },
{ 0x000290, 16, 0x01, 0x00000000 },
{ 0x0003b0, 16, 0x01, 0x00000000 },
{ 0x0002a0, 16, 0x01, 0x00000000 },
{ 0x000420, 16, 0x01, 0x00000000 },
{ 0x0002b0, 16, 0x01, 0x00000000 },
{ 0x000430, 16, 0x01, 0x00000000 },
{ 0x0002c0, 16, 0x01, 0x00000000 },
{ 0x0004d0, 16, 0x01, 0x00000000 },
{ 0x000720, 16, 0x01, 0x00000000 },
{ 0x0008c0, 16, 0x01, 0x00000000 },
{ 0x000890, 16, 0x01, 0x00000000 },
{ 0x0008e0, 16, 0x01, 0x00000000 },
{ 0x0008a0, 16, 0x01, 0x00000000 },
{ 0x0008f0, 16, 0x01, 0x00000000 },
{ 0x00094c, 1, 0x01, 0x000000ff },
{ 0x00094d, 1, 0x01, 0xffffffff },
{ 0x00094e, 1, 0x01, 0x00000002 },
{ 0x0002ec, 1, 0x01, 0x00000001 },
{ 0x000303, 1, 0x01, 0x00000001 },
{ 0x0002e6, 1, 0x01, 0x00000001 },
{ 0x000466, 1, 0x01, 0x00000052 },
{ 0x000301, 1, 0x01, 0x3f800000 },
{ 0x000304, 1, 0x01, 0x30201000 },
{ 0x000305, 1, 0x01, 0x70605040 },
{ 0x000306, 1, 0x01, 0xb8a89888 },
{ 0x000307, 1, 0x01, 0xf8e8d8c8 },
{ 0x00030a, 1, 0x01, 0x00ffff00 },
{ 0x00030b, 1, 0x01, 0x0000001a },
{ 0x00030c, 1, 0x01, 0x00000001 },
{ 0x000318, 1, 0x01, 0x00000001 },
{ 0x000340, 1, 0x01, 0x00000000 },
{ 0x000375, 1, 0x01, 0x00000001 },
{ 0x000351, 1, 0x01, 0x00000100 },
{ 0x00037d, 1, 0x01, 0x00000006 },
{ 0x0003a0, 1, 0x01, 0x00000002 },
{ 0x0003aa, 1, 0x01, 0x00000001 },
{ 0x0003a9, 1, 0x01, 0x00000001 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000360, 1, 0x01, 0x00000040 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00001fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x003fffff },
{ 0x00037a, 1, 0x01, 0x00000012 },
{ 0x0005e0, 5, 0x01, 0x00000022 },
{ 0x000619, 1, 0x01, 0x00000003 },
{ 0x000811, 1, 0x01, 0x00000003 },
{ 0x000812, 1, 0x01, 0x00000004 },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000815, 1, 0x01, 0x0000000b },
{ 0x000800, 6, 0x01, 0x00000001 },
{ 0x000632, 1, 0x01, 0x00000001 },
{ 0x000633, 1, 0x01, 0x00000002 },
{ 0x000634, 1, 0x01, 0x00000003 },
{ 0x000635, 1, 0x01, 0x00000004 },
{ 0x000654, 1, 0x01, 0x3f800000 },
{ 0x000657, 1, 0x01, 0x3f800000 },
{ 0x000655, 2, 0x01, 0x3f800000 },
{ 0x0006cd, 1, 0x01, 0x3f800000 },
{ 0x0007f5, 1, 0x01, 0x3f800000 },
{ 0x0007dc, 1, 0x01, 0x39291909 },
{ 0x0007dd, 1, 0x01, 0x79695949 },
{ 0x0007de, 1, 0x01, 0xb9a99989 },
{ 0x0007df, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007e8, 1, 0x01, 0x00003210 },
{ 0x0007e9, 1, 0x01, 0x00007654 },
{ 0x0007ea, 1, 0x01, 0x00000098 },
{ 0x0007ec, 1, 0x01, 0x39291909 },
{ 0x0007ed, 1, 0x01, 0x79695949 },
{ 0x0007ee, 1, 0x01, 0xb9a99989 },
{ 0x0007ef, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007f0, 1, 0x01, 0x00003210 },
{ 0x0007f1, 1, 0x01, 0x00007654 },
{ 0x0007f2, 1, 0x01, 0x00000098 },
{ 0x0005a5, 1, 0x01, 0x00000001 },
{ 0x000980, 128, 0x01, 0x00000000 },
{ 0x000468, 1, 0x01, 0x00000004 },
{ 0x00046c, 1, 0x01, 0x00000001 },
{ 0x000470, 96, 0x01, 0x00000000 },
{ 0x000510, 16, 0x01, 0x3f800000 },
{ 0x000520, 1, 0x01, 0x000002b6 },
{ 0x000529, 1, 0x01, 0x00000001 },
{ 0x000530, 16, 0x01, 0xffff0000 },
{ 0x000585, 1, 0x01, 0x0000003f },
{ 0x000576, 1, 0x01, 0x00000003 },
{ 0x00057b, 1, 0x01, 0x00000059 },
{ 0x000586, 1, 0x01, 0x00000040 },
{ 0x000582, 2, 0x01, 0x00000080 },
{ 0x0005c2, 1, 0x01, 0x00000001 },
{ 0x000638, 2, 0x01, 0x00000001 },
{ 0x00063a, 1, 0x01, 0x00000002 },
{ 0x00063b, 2, 0x01, 0x00000001 },
{ 0x00063d, 1, 0x01, 0x00000002 },
{ 0x00063e, 1, 0x01, 0x00000001 },
{ 0x0008b8, 8, 0x01, 0x00000001 },
{ 0x000900, 8, 0x01, 0x00000001 },
{ 0x000908, 8, 0x01, 0x00000002 },
{ 0x000910, 16, 0x01, 0x00000001 },
{ 0x000920, 8, 0x01, 0x00000002 },
{ 0x000928, 8, 0x01, 0x00000001 },
{ 0x000648, 9, 0x01, 0x00000001 },
{ 0x000658, 1, 0x01, 0x0000000f },
{ 0x0007ff, 1, 0x01, 0x0000000a },
{ 0x00066a, 1, 0x01, 0x40000000 },
{ 0x00066b, 1, 0x01, 0x10000000 },
{ 0x00066c, 2, 0x01, 0xffff0000 },
{ 0x0007af, 2, 0x01, 0x00000008 },
{ 0x0007f6, 1, 0x01, 0x00000001 },
{ 0x0006b2, 1, 0x01, 0x00000055 },
{ 0x0007ad, 1, 0x01, 0x00000003 },
{ 0x000937, 1, 0x01, 0x00000001 },
{ 0x000971, 1, 0x01, 0x00000008 },
{ 0x000972, 1, 0x01, 0x00000040 },
{ 0x000973, 1, 0x01, 0x0000012c },
{ 0x00097c, 1, 0x01, 0x00000040 },
{ 0x000979, 1, 0x01, 0x00000003 },
{ 0x000975, 1, 0x01, 0x00000020 },
{ 0x000976, 1, 0x01, 0x00000001 },
{ 0x000977, 1, 0x01, 0x00000020 },
{ 0x000978, 1, 0x01, 0x00000001 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095e, 1, 0x01, 0x20164010 },
{ 0x00095f, 1, 0x01, 0x00000020 },
{ 0x000683, 1, 0x01, 0x00000006 },
{ 0x000685, 1, 0x01, 0x003fffff },
{ 0x000687, 1, 0x01, 0x00000c48 },
{ 0x0006a0, 1, 0x01, 0x00000005 },
{ 0x000840, 1, 0x01, 0x00300008 },
{ 0x000841, 1, 0x01, 0x04000080 },
{ 0x000842, 1, 0x01, 0x00300008 },
{ 0x000843, 1, 0x01, 0x04000080 },
{ 0x000818, 8, 0x01, 0x00000000 },
{ 0x000848, 16, 0x01, 0x00000000 },
{ 0x000738, 1, 0x01, 0x00000000 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ab, 1, 0x01, 0x00000002 },
{ 0x0006ac, 1, 0x01, 0x00000080 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x0006bb, 1, 0x01, 0x000000cf },
{ 0x0006ce, 1, 0x01, 0x2a712488 },
{ 0x000739, 1, 0x01, 0x4085c000 },
{ 0x00073a, 1, 0x01, 0x00000080 },
{ 0x000786, 1, 0x01, 0x80000100 },
{ 0x00073c, 1, 0x01, 0x00010100 },
{ 0x00073d, 1, 0x01, 0x02800000 },
{ 0x000787, 1, 0x01, 0x000000cf },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x000836, 1, 0x01, 0x00000001 },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x00080c, 1, 0x01, 0x00000002 },
{ 0x00080d, 2, 0x01, 0x00000100 },
{ 0x00080f, 1, 0x01, 0x00000001 },
{ 0x000823, 1, 0x01, 0x00000002 },
{ 0x000824, 2, 0x01, 0x00000100 },
{ 0x000826, 1, 0x01, 0x00000001 },
{ 0x00095d, 1, 0x01, 0x00000001 },
{ 0x00082b, 1, 0x01, 0x00000004 },
{ 0x000942, 1, 0x01, 0x00010001 },
{ 0x000943, 1, 0x01, 0x00000001 },
{ 0x000944, 1, 0x01, 0x00000022 },
{ 0x0007c5, 1, 0x01, 0x00010001 },
{ 0x000834, 1, 0x01, 0x00000001 },
{ 0x0007c7, 1, 0x01, 0x00000001 },
{ 0x00c1b0, 8, 0x01, 0x0000000f },
{ 0x00c1b8, 1, 0x01, 0x0fac6881 },
{ 0x00c1b9, 1, 0x01, 0x00fac688 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000002 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000014 },
{ 0x000351, 1, 0x01, 0x00000100 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095d, 1, 0x01, 0x00000001 },
{ 0x00082b, 1, 0x01, 0x00000004 },
{ 0x000942, 1, 0x01, 0x00010001 },
{ 0x000943, 1, 0x01, 0x00000001 },
{ 0x0007c5, 1, 0x01, 0x00010001 },
{ 0x000834, 1, 0x01, 0x00000001 },
{ 0x0007c7, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000001 },
{ 0x00080c, 1, 0x01, 0x00000002 },
{ 0x00080d, 2, 0x01, 0x00000100 },
{ 0x00080f, 1, 0x01, 0x00000001 },
{ 0x000823, 1, 0x01, 0x00000002 },
{ 0x000824, 2, 0x01, 0x00000100 },
{ 0x000826, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
nvc1_grctx_pack_icmd[] = {
{ nvc1_grctx_init_icmd_0 },
{}
};
const struct nvc0_graph_init
nvc1_grctx_init_9097_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
{ 0x00080c, 8, 0x40, 0x00000300 },
{ 0x000810, 1, 0x04, 0x000000cf },
{ 0x000850, 7, 0x40, 0x00000000 },
{ 0x000814, 8, 0x40, 0x00000040 },
{ 0x000818, 8, 0x40, 0x00000001 },
{ 0x00081c, 8, 0x40, 0x00000000 },
{ 0x000820, 8, 0x40, 0x00000000 },
{ 0x002700, 8, 0x20, 0x00000000 },
{ 0x002704, 8, 0x20, 0x00000000 },
{ 0x002708, 8, 0x20, 0x00000000 },
{ 0x00270c, 8, 0x20, 0x00000000 },
{ 0x002710, 8, 0x20, 0x00014000 },
{ 0x002714, 8, 0x20, 0x00000040 },
{ 0x001c00, 16, 0x10, 0x00000000 },
{ 0x001c04, 16, 0x10, 0x00000000 },
{ 0x001c08, 16, 0x10, 0x00000000 },
{ 0x001c0c, 16, 0x10, 0x00000000 },
{ 0x001d00, 16, 0x10, 0x00000000 },
{ 0x001d04, 16, 0x10, 0x00000000 },
{ 0x001d08, 16, 0x10, 0x00000000 },
{ 0x001d0c, 16, 0x10, 0x00000000 },
{ 0x001f00, 16, 0x08, 0x00000000 },
{ 0x001f04, 16, 0x08, 0x00000000 },
{ 0x001f80, 16, 0x08, 0x00000000 },
{ 0x001f84, 16, 0x08, 0x00000000 },
{ 0x002200, 5, 0x10, 0x00000022 },
{ 0x002000, 1, 0x04, 0x00000000 },
{ 0x002040, 1, 0x04, 0x00000011 },
{ 0x002080, 1, 0x04, 0x00000020 },
{ 0x0020c0, 1, 0x04, 0x00000030 },
{ 0x002100, 1, 0x04, 0x00000040 },
{ 0x002140, 1, 0x04, 0x00000051 },
{ 0x00200c, 6, 0x40, 0x00000001 },
{ 0x002010, 1, 0x04, 0x00000000 },
{ 0x002050, 1, 0x04, 0x00000000 },
{ 0x002090, 1, 0x04, 0x00000001 },
{ 0x0020d0, 1, 0x04, 0x00000002 },
{ 0x002110, 1, 0x04, 0x00000003 },
{ 0x002150, 1, 0x04, 0x00000004 },
{ 0x000380, 4, 0x20, 0x00000000 },
{ 0x000384, 4, 0x20, 0x00000000 },
{ 0x000388, 4, 0x20, 0x00000000 },
{ 0x00038c, 4, 0x20, 0x00000000 },
{ 0x000700, 4, 0x10, 0x00000000 },
{ 0x000704, 4, 0x10, 0x00000000 },
{ 0x000708, 4, 0x10, 0x00000000 },
{ 0x002800, 128, 0x04, 0x00000000 },
{ 0x000a00, 16, 0x20, 0x00000000 },
{ 0x000a04, 16, 0x20, 0x00000000 },
{ 0x000a08, 16, 0x20, 0x00000000 },
{ 0x000a0c, 16, 0x20, 0x00000000 },
{ 0x000a10, 16, 0x20, 0x00000000 },
{ 0x000a14, 16, 0x20, 0x00000000 },
{ 0x000c00, 16, 0x10, 0x00000000 },
{ 0x000c04, 16, 0x10, 0x00000000 },
{ 0x000c08, 16, 0x10, 0x00000000 },
{ 0x000c0c, 16, 0x10, 0x3f800000 },
{ 0x000d00, 8, 0x08, 0xffff0000 },
{ 0x000d04, 8, 0x08, 0xffff0000 },
{ 0x000e00, 16, 0x10, 0x00000000 },
{ 0x000e04, 16, 0x10, 0xffff0000 },
{ 0x000e08, 16, 0x10, 0xffff0000 },
{ 0x000d40, 4, 0x08, 0x00000000 },
{ 0x000d44, 4, 0x08, 0x00000000 },
{ 0x001e00, 8, 0x20, 0x00000001 },
{ 0x001e04, 8, 0x20, 0x00000001 },
{ 0x001e08, 8, 0x20, 0x00000002 },
{ 0x001e0c, 8, 0x20, 0x00000001 },
{ 0x001e10, 8, 0x20, 0x00000001 },
{ 0x001e14, 8, 0x20, 0x00000002 },
{ 0x001e18, 8, 0x20, 0x00000001 },
{ 0x00030c, 1, 0x04, 0x00000001 },
{ 0x001944, 1, 0x04, 0x00000000 },
{ 0x001514, 1, 0x04, 0x00000000 },
{ 0x000d68, 1, 0x04, 0x0000ffff },
{ 0x00121c, 1, 0x04, 0x0fac6881 },
{ 0x000fac, 1, 0x04, 0x00000001 },
{ 0x001538, 1, 0x04, 0x00000001 },
{ 0x000fe0, 2, 0x04, 0x00000000 },
{ 0x000fe8, 1, 0x04, 0x00000014 },
{ 0x000fec, 1, 0x04, 0x00000040 },
{ 0x000ff0, 1, 0x04, 0x00000000 },
{ 0x00179c, 1, 0x04, 0x00000000 },
{ 0x001228, 1, 0x04, 0x00000400 },
{ 0x00122c, 1, 0x04, 0x00000300 },
{ 0x001230, 1, 0x04, 0x00010001 },
{ 0x0007f8, 1, 0x04, 0x00000000 },
{ 0x0015b4, 1, 0x04, 0x00000001 },
{ 0x0015cc, 1, 0x04, 0x00000000 },
{ 0x001534, 1, 0x04, 0x00000000 },
{ 0x000fb0, 1, 0x04, 0x00000000 },
{ 0x0015d0, 1, 0x04, 0x00000000 },
{ 0x00153c, 1, 0x04, 0x00000000 },
{ 0x0016b4, 1, 0x04, 0x00000003 },
{ 0x000fbc, 4, 0x04, 0x0000ffff },
{ 0x000df8, 2, 0x04, 0x00000000 },
{ 0x001948, 1, 0x04, 0x00000000 },
{ 0x001970, 1, 0x04, 0x00000001 },
{ 0x00161c, 1, 0x04, 0x000009f0 },
{ 0x000dcc, 1, 0x04, 0x00000010 },
{ 0x00163c, 1, 0x04, 0x00000000 },
{ 0x0015e4, 1, 0x04, 0x00000000 },
{ 0x001160, 32, 0x04, 0x25e00040 },
{ 0x001880, 32, 0x04, 0x00000000 },
{ 0x000f84, 2, 0x04, 0x00000000 },
{ 0x0017c8, 2, 0x04, 0x00000000 },
{ 0x0017d0, 1, 0x04, 0x000000ff },
{ 0x0017d4, 1, 0x04, 0xffffffff },
{ 0x0017d8, 1, 0x04, 0x00000002 },
{ 0x0017dc, 1, 0x04, 0x00000000 },
{ 0x0015f4, 2, 0x04, 0x00000000 },
{ 0x001434, 2, 0x04, 0x00000000 },
{ 0x000d74, 1, 0x04, 0x00000000 },
{ 0x000dec, 1, 0x04, 0x00000001 },
{ 0x0013a4, 1, 0x04, 0x00000000 },
{ 0x001318, 1, 0x04, 0x00000001 },
{ 0x001644, 1, 0x04, 0x00000000 },
{ 0x000748, 1, 0x04, 0x00000000 },
{ 0x000de8, 1, 0x04, 0x00000000 },
{ 0x001648, 1, 0x04, 0x00000000 },
{ 0x0012a4, 1, 0x04, 0x00000000 },
{ 0x001120, 4, 0x04, 0x00000000 },
{ 0x001118, 1, 0x04, 0x00000000 },
{ 0x00164c, 1, 0x04, 0x00000000 },
{ 0x001658, 1, 0x04, 0x00000000 },
{ 0x001910, 1, 0x04, 0x00000290 },
{ 0x001518, 1, 0x04, 0x00000000 },
{ 0x00165c, 1, 0x04, 0x00000001 },
{ 0x001520, 1, 0x04, 0x00000000 },
{ 0x001604, 1, 0x04, 0x00000000 },
{ 0x001570, 1, 0x04, 0x00000000 },
{ 0x0013b0, 2, 0x04, 0x3f800000 },
{ 0x00020c, 1, 0x04, 0x00000000 },
{ 0x001670, 1, 0x04, 0x30201000 },
{ 0x001674, 1, 0x04, 0x70605040 },
{ 0x001678, 1, 0x04, 0xb8a89888 },
{ 0x00167c, 1, 0x04, 0xf8e8d8c8 },
{ 0x00166c, 1, 0x04, 0x00000000 },
{ 0x001680, 1, 0x04, 0x00ffff00 },
{ 0x0012d0, 1, 0x04, 0x00000003 },
{ 0x0012d4, 1, 0x04, 0x00000002 },
{ 0x001684, 2, 0x04, 0x00000000 },
{ 0x000dac, 2, 0x04, 0x00001b02 },
{ 0x000db4, 1, 0x04, 0x00000000 },
{ 0x00168c, 1, 0x04, 0x00000000 },
{ 0x0015bc, 1, 0x04, 0x00000000 },
{ 0x00156c, 1, 0x04, 0x00000000 },
{ 0x00187c, 1, 0x04, 0x00000000 },
{ 0x001110, 1, 0x04, 0x00000001 },
{ 0x000dc0, 3, 0x04, 0x00000000 },
{ 0x001234, 1, 0x04, 0x00000000 },
{ 0x001690, 1, 0x04, 0x00000000 },
{ 0x0012ac, 1, 0x04, 0x00000001 },
{ 0x0002c4, 1, 0x04, 0x00000000 },
{ 0x000790, 5, 0x04, 0x00000000 },
{ 0x00077c, 1, 0x04, 0x00000000 },
{ 0x001000, 1, 0x04, 0x00000010 },
{ 0x0010fc, 1, 0x04, 0x00000000 },
{ 0x001290, 1, 0x04, 0x00000000 },
{ 0x000218, 1, 0x04, 0x00000010 },
{ 0x0012d8, 1, 0x04, 0x00000000 },
{ 0x0012dc, 1, 0x04, 0x00000010 },
{ 0x000d94, 1, 0x04, 0x00000001 },
{ 0x00155c, 2, 0x04, 0x00000000 },
{ 0x001564, 1, 0x04, 0x00001fff },
{ 0x001574, 2, 0x04, 0x00000000 },
{ 0x00157c, 1, 0x04, 0x003fffff },
{ 0x001354, 1, 0x04, 0x00000000 },
{ 0x001664, 1, 0x04, 0x00000000 },
{ 0x001610, 1, 0x04, 0x00000012 },
{ 0x001608, 2, 0x04, 0x00000000 },
{ 0x00162c, 1, 0x04, 0x00000003 },
{ 0x000210, 1, 0x04, 0x00000000 },
{ 0x000320, 1, 0x04, 0x00000000 },
{ 0x000324, 6, 0x04, 0x3f800000 },
{ 0x000750, 1, 0x04, 0x00000000 },
{ 0x000760, 1, 0x04, 0x39291909 },
{ 0x000764, 1, 0x04, 0x79695949 },
{ 0x000768, 1, 0x04, 0xb9a99989 },
{ 0x00076c, 1, 0x04, 0xf9e9d9c9 },
{ 0x000770, 1, 0x04, 0x30201000 },
{ 0x000774, 1, 0x04, 0x70605040 },
{ 0x000778, 1, 0x04, 0x00009080 },
{ 0x000780, 1, 0x04, 0x39291909 },
{ 0x000784, 1, 0x04, 0x79695949 },
{ 0x000788, 1, 0x04, 0xb9a99989 },
{ 0x00078c, 1, 0x04, 0xf9e9d9c9 },
{ 0x0007d0, 1, 0x04, 0x30201000 },
{ 0x0007d4, 1, 0x04, 0x70605040 },
{ 0x0007d8, 1, 0x04, 0x00009080 },
{ 0x00037c, 1, 0x04, 0x00000001 },
{ 0x000740, 2, 0x04, 0x00000000 },
{ 0x002600, 1, 0x04, 0x00000000 },
{ 0x001918, 1, 0x04, 0x00000000 },
{ 0x00191c, 1, 0x04, 0x00000900 },
{ 0x001920, 1, 0x04, 0x00000405 },
{ 0x001308, 1, 0x04, 0x00000001 },
{ 0x001924, 1, 0x04, 0x00000000 },
{ 0x0013ac, 1, 0x04, 0x00000000 },
{ 0x00192c, 1, 0x04, 0x00000001 },
{ 0x00193c, 1, 0x04, 0x00002c1c },
{ 0x000d7c, 1, 0x04, 0x00000000 },
{ 0x000f8c, 1, 0x04, 0x00000000 },
{ 0x0002c0, 1, 0x04, 0x00000001 },
{ 0x001510, 1, 0x04, 0x00000000 },
{ 0x001940, 1, 0x04, 0x00000000 },
{ 0x000ff4, 2, 0x04, 0x00000000 },
{ 0x00194c, 2, 0x04, 0x00000000 },
{ 0x001968, 1, 0x04, 0x00000000 },
{ 0x001590, 1, 0x04, 0x0000003f },
{ 0x0007e8, 4, 0x04, 0x00000000 },
{ 0x00196c, 1, 0x04, 0x00000011 },
{ 0x00197c, 1, 0x04, 0x00000000 },
{ 0x000fcc, 2, 0x04, 0x00000000 },
{ 0x0002d8, 1, 0x04, 0x00000040 },
{ 0x001980, 1, 0x04, 0x00000080 },
{ 0x001504, 1, 0x04, 0x00000080 },
{ 0x001984, 1, 0x04, 0x00000000 },
{ 0x000300, 1, 0x04, 0x00000001 },
{ 0x0013a8, 1, 0x04, 0x00000000 },
{ 0x0012ec, 1, 0x04, 0x00000000 },
{ 0x001310, 1, 0x04, 0x00000000 },
{ 0x001314, 1, 0x04, 0x00000001 },
{ 0x001380, 1, 0x04, 0x00000000 },
{ 0x001384, 4, 0x04, 0x00000001 },
{ 0x001394, 1, 0x04, 0x00000000 },
{ 0x00139c, 1, 0x04, 0x00000000 },
{ 0x001398, 1, 0x04, 0x00000000 },
{ 0x001594, 1, 0x04, 0x00000000 },
{ 0x001598, 4, 0x04, 0x00000001 },
{ 0x000f54, 3, 0x04, 0x00000000 },
{ 0x0019bc, 1, 0x04, 0x00000000 },
{ 0x000f9c, 2, 0x04, 0x00000000 },
{ 0x0012cc, 1, 0x04, 0x00000000 },
{ 0x0012e8, 1, 0x04, 0x00000000 },
{ 0x00130c, 1, 0x04, 0x00000001 },
{ 0x001360, 8, 0x04, 0x00000000 },
{ 0x00133c, 2, 0x04, 0x00000001 },
{ 0x001344, 1, 0x04, 0x00000002 },
{ 0x001348, 2, 0x04, 0x00000001 },
{ 0x001350, 1, 0x04, 0x00000002 },
{ 0x001358, 1, 0x04, 0x00000001 },
{ 0x0012e4, 1, 0x04, 0x00000000 },
{ 0x00131c, 4, 0x04, 0x00000000 },
{ 0x0019c0, 1, 0x04, 0x00000000 },
{ 0x001140, 1, 0x04, 0x00000000 },
{ 0x0019c4, 1, 0x04, 0x00000000 },
{ 0x0019c8, 1, 0x04, 0x00001500 },
{ 0x00135c, 1, 0x04, 0x00000000 },
{ 0x000f90, 1, 0x04, 0x00000000 },
{ 0x0019e0, 8, 0x04, 0x00000001 },
{ 0x0019cc, 1, 0x04, 0x00000001 },
{ 0x0015b8, 1, 0x04, 0x00000000 },
{ 0x001a00, 1, 0x04, 0x00001111 },
{ 0x001a04, 7, 0x04, 0x00000000 },
{ 0x000d6c, 2, 0x04, 0xffff0000 },
{ 0x0010f8, 1, 0x04, 0x00001010 },
{ 0x000d80, 5, 0x04, 0x00000000 },
{ 0x000da0, 1, 0x04, 0x00000000 },
{ 0x001508, 1, 0x04, 0x80000000 },
{ 0x00150c, 1, 0x04, 0x40000000 },
{ 0x001668, 1, 0x04, 0x00000000 },
{ 0x000318, 2, 0x04, 0x00000008 },
{ 0x000d9c, 1, 0x04, 0x00000001 },
{ 0x0007dc, 1, 0x04, 0x00000000 },
{ 0x00074c, 1, 0x04, 0x00000055 },
{ 0x001420, 1, 0x04, 0x00000003 },
{ 0x0017bc, 2, 0x04, 0x00000000 },
{ 0x0017c4, 1, 0x04, 0x00000001 },
{ 0x001008, 1, 0x04, 0x00000008 },
{ 0x00100c, 1, 0x04, 0x00000040 },
{ 0x001010, 1, 0x04, 0x0000012c },
{ 0x000d60, 1, 0x04, 0x00000040 },
{ 0x00075c, 1, 0x04, 0x00000003 },
{ 0x001018, 1, 0x04, 0x00000020 },
{ 0x00101c, 1, 0x04, 0x00000001 },
{ 0x001020, 1, 0x04, 0x00000020 },
{ 0x001024, 1, 0x04, 0x00000001 },
{ 0x001444, 3, 0x04, 0x00000000 },
{ 0x000360, 1, 0x04, 0x20164010 },
{ 0x000364, 1, 0x04, 0x00000020 },
{ 0x000368, 1, 0x04, 0x00000000 },
{ 0x000de4, 1, 0x04, 0x00000000 },
{ 0x000204, 1, 0x04, 0x00000006 },
{ 0x000208, 1, 0x04, 0x00000000 },
{ 0x0002cc, 1, 0x04, 0x003fffff },
{ 0x0002d0, 1, 0x04, 0x00000c48 },
{ 0x001220, 1, 0x04, 0x00000005 },
{ 0x000fdc, 1, 0x04, 0x00000000 },
{ 0x000f98, 1, 0x04, 0x00300008 },
{ 0x001284, 1, 0x04, 0x04000080 },
{ 0x001450, 1, 0x04, 0x00300008 },
{ 0x001454, 1, 0x04, 0x04000080 },
{ 0x000214, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvc1_grctx_init_9197_0[] = {
{ 0x003400, 128, 0x04, 0x00000000 },
{ 0x0002e4, 1, 0x04, 0x0000b001 },
{}
};
static const struct nvc0_graph_pack
nvc1_grctx_pack_mthd[] = {
{ nvc1_grctx_init_9097_0, 0x9097 },
{ nvc1_grctx_init_9197_0, 0x9197 },
{ nvc0_grctx_init_902d_0, 0x902d },
{ nvc0_grctx_init_9039_0, 0x9039 },
{ nvc0_grctx_init_90c0_0, 0x90c0 },
{}
};
static const struct nvc0_graph_init
nvc1_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180218 },
{ 0x405834, 2, 0x04, 0x00000000 },
{ 0x405854, 1, 0x04, 0x00000000 },
{ 0x405870, 4, 0x04, 0x00000001 },
{ 0x405a00, 2, 0x04, 0x00000000 },
{ 0x405a18, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvc1_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
{ 0x4064ac, 1, 0x04, 0x00003fff },
{ 0x4064b4, 2, 0x04, 0x00000000 },
{ 0x4064c0, 1, 0x04, 0x80140078 },
{ 0x4064c4, 1, 0x04, 0x0086ffff },
{}
};
static const struct nvc0_graph_init
nvc1_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x02802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
{ 0x408900, 1, 0x04, 0x3080b801 },
{ 0x408904, 1, 0x04, 0x62000001 },
{ 0x408908, 1, 0x04, 0x00c80929 },
{ 0x408980, 1, 0x04, 0x0000011d },
{}
};
static const struct nvc0_graph_pack
nvc1_grctx_pack_hub[] = {
{ nvc0_grctx_init_main_0 },
{ nvc0_grctx_init_fe_0 },
{ nvc0_grctx_init_pri_0 },
{ nvc0_grctx_init_memfmt_0 },
{ nvc1_grctx_init_ds_0 },
{ nvc1_grctx_init_pd_0 },
{ nvc0_grctx_init_rstr2d_0 },
{ nvc0_grctx_init_scc_0 },
{ nvc1_grctx_init_be_0 },
{}
};
static const struct nvc0_graph_init
nvc1_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x0006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
{ 0x418830, 1, 0x04, 0x10000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x00100018 },
{}
};
const struct nvc0_graph_init
nvc1_grctx_init_gpm_0[] = {
{ 0x418c08, 1, 0x04, 0x00000001 },
{ 0x418c10, 8, 0x04, 0x00000000 },
{ 0x418c6c, 1, 0x04, 0x00000001 },
{ 0x418c80, 1, 0x04, 0x20200004 },
{ 0x418c8c, 1, 0x04, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
nvc1_grctx_pack_gpc[] = {
{ nvc0_grctx_init_gpc_unk_0 },
{ nvc0_grctx_init_prop_0 },
{ nvc0_grctx_init_gpc_unk_1 },
{ nvc1_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nvc0_grctx_init_crstr_0 },
{ nvc1_grctx_init_gpm_0 },
{ nvc0_grctx_init_gcc_0 },
{}
};
const struct nvc0_graph_init
nvc1_grctx_init_pe_0[] = {
{ 0x419818, 1, 0x04, 0x00000000 },
{ 0x41983c, 1, 0x04, 0x00038bc7 },
{ 0x419848, 1, 0x04, 0x00000000 },
{ 0x419864, 1, 0x04, 0x00000129 },
{ 0x419888, 1, 0x04, 0x00000000 },
{}
};
const struct nvc0_graph_init
nvc1_grctx_init_wwdx_0[] = {
{ 0x419b00, 1, 0x04, 0x0a418820 },
{ 0x419b04, 1, 0x04, 0x062080e6 },
{ 0x419b08, 1, 0x04, 0x020398a4 },
{ 0x419b0c, 1, 0x04, 0x0e629062 },
{ 0x419b10, 1, 0x04, 0x0a418820 },
{ 0x419b14, 1, 0x04, 0x000000e6 },
{ 0x419bd0, 1, 0x04, 0x00900103 },
{ 0x419be0, 1, 0x04, 0x00400001 },
{ 0x419be4, 1, 0x04, 0x00000000 },
{}
};
const struct nvc0_graph_init
nvc1_grctx_init_tpccs_0[] = {
{ 0x419d20, 1, 0x04, 0x12180000 },
{ 0x419d24, 1, 0x04, 0x00001fff },
{ 0x419d44, 1, 0x04, 0x02180218 },
{}
};
static const struct nvc0_graph_pack
nvc1_grctx_pack_tpc[] = {
{ nvc1_grctx_init_pe_0 },
{ nvc4_grctx_init_tex_0 },
{ nvc1_grctx_init_wwdx_0 },
{ nvc0_grctx_init_mpc_0 },
{ nvc4_grctx_init_l1c_0 },
{ nvc1_grctx_init_tpccs_0 },
{ nvc4_grctx_init_sm_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
void
nvc1_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
int gpc, tpc;
u32 offset;
mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
mmio_list(0x408004, 0x00000000, 8, 0);
mmio_list(0x408008, 0x80000018, 0, 0);
mmio_list(0x40800c, 0x00000000, 8, 1);
mmio_list(0x408010, 0x80000000, 0, 0);
mmio_list(0x418810, 0x80000000, 12, 2);
mmio_list(0x419848, 0x10000000, 12, 2);
mmio_list(0x419004, 0x00000000, 8, 1);
mmio_list(0x419008, 0x00000000, 0, 0);
mmio_list(0x418808, 0x00000000, 8, 0);
mmio_list(0x41880c, 0x80000018, 0, 0);
mmio_list(0x405830, 0x02180218, 0, 0);
mmio_list(0x4064c4, 0x0086ffff, 0, 0);
for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
u32 addr = TPC_UNIT(gpc, tpc, 0x0520);
mmio_list(addr, 0x12180000 | offset, 0, 0);
offset += 0x0324;
}
for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
u32 addr = TPC_UNIT(gpc, tpc, 0x0544);
mmio_list(addr, 0x02180000 | offset, 0, 0);
offset += 0x0324;
}
}
}
void
nvc1_grctx_generate_unkn(struct nvc0_graph_priv *priv)
{
nv_mask(priv, 0x418c6c, 0x00000001, 0x00000001);
nv_mask(priv, 0x41980c, 0x00000010, 0x00000010);
nv_mask(priv, 0x419814, 0x00000004, 0x00000004);
nv_mask(priv, 0x4064c0, 0x80000000, 0x80000000);
nv_mask(priv, 0x405800, 0x08000000, 0x08000000);
nv_mask(priv, 0x419c00, 0x00000008, 0x00000008);
}
struct nouveau_oclass *
nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc1),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nvc0_grctx_generate_main,
.mods = nvc1_grctx_generate_mods,
.unkn = nvc1_grctx_generate_unkn,
.hub = nvc1_grctx_pack_hub,
.gpc = nvc1_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nvc1_grctx_pack_tpc,
.icmd = nvc1_grctx_pack_icmd,
.mthd = nvc1_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,103 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
const struct nvc0_graph_init
nvc4_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
{ 0x419a0c, 1, 0x04, 0x00020000 },
{ 0x419a10, 1, 0x04, 0x00000000 },
{ 0x419a14, 1, 0x04, 0x00000200 },
{ 0x419a1c, 1, 0x04, 0x00000000 },
{ 0x419a20, 1, 0x04, 0x00000800 },
{ 0x419ac4, 1, 0x04, 0x0007f440 },
{}
};
const struct nvc0_graph_init
nvc4_grctx_init_l1c_0[] = {
{ 0x419cb0, 1, 0x04, 0x00020048 },
{ 0x419ce8, 1, 0x04, 0x00000000 },
{ 0x419cf4, 1, 0x04, 0x00000183 },
{}
};
const struct nvc0_graph_init
nvc4_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00000002 },
{ 0x419e44, 1, 0x04, 0x001beff2 },
{ 0x419e48, 1, 0x04, 0x00000000 },
{ 0x419e4c, 1, 0x04, 0x0000000f },
{ 0x419e50, 17, 0x04, 0x00000000 },
{ 0x419e98, 1, 0x04, 0x00000000 },
{ 0x419ee0, 1, 0x04, 0x00011110 },
{ 0x419f30, 11, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
nvc4_grctx_pack_tpc[] = {
{ nvc0_grctx_init_pe_0 },
{ nvc4_grctx_init_tex_0 },
{ nvc0_grctx_init_wwdx_0 },
{ nvc0_grctx_init_mpc_0 },
{ nvc4_grctx_init_l1c_0 },
{ nvc0_grctx_init_tpccs_0 },
{ nvc4_grctx_init_sm_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
struct nouveau_oclass *
nvc4_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc3),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nvc0_grctx_generate_main,
.mods = nvc0_grctx_generate_mods,
.unkn = nvc0_grctx_generate_unkn,
.hub = nvc0_grctx_pack_hub,
.gpc = nvc0_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nvc4_grctx_pack_tpc,
.icmd = nvc0_grctx_pack_icmd,
.mthd = nvc0_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,354 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
nvc8_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
{ 0x00003d, 1, 0x01, 0x00000001 },
{ 0x0000e8, 8, 0x01, 0x00000400 },
{ 0x000078, 8, 0x01, 0x00000300 },
{ 0x000050, 1, 0x01, 0x00000011 },
{ 0x000058, 8, 0x01, 0x00000008 },
{ 0x000208, 8, 0x01, 0x00000001 },
{ 0x000081, 1, 0x01, 0x00000001 },
{ 0x000085, 1, 0x01, 0x00000004 },
{ 0x000088, 1, 0x01, 0x00000400 },
{ 0x000090, 1, 0x01, 0x00000300 },
{ 0x000098, 1, 0x01, 0x00001001 },
{ 0x0000e3, 1, 0x01, 0x00000001 },
{ 0x0000da, 1, 0x01, 0x00000001 },
{ 0x0000f8, 1, 0x01, 0x00000003 },
{ 0x0000fa, 1, 0x01, 0x00000001 },
{ 0x00009f, 4, 0x01, 0x0000ffff },
{ 0x0000b1, 1, 0x01, 0x00000001 },
{ 0x0000b2, 40, 0x01, 0x00000000 },
{ 0x000210, 8, 0x01, 0x00000040 },
{ 0x000218, 8, 0x01, 0x0000c080 },
{ 0x0000ad, 1, 0x01, 0x0000013e },
{ 0x0000e1, 1, 0x01, 0x00000010 },
{ 0x000290, 16, 0x01, 0x00000000 },
{ 0x0003b0, 16, 0x01, 0x00000000 },
{ 0x0002a0, 16, 0x01, 0x00000000 },
{ 0x000420, 16, 0x01, 0x00000000 },
{ 0x0002b0, 16, 0x01, 0x00000000 },
{ 0x000430, 16, 0x01, 0x00000000 },
{ 0x0002c0, 16, 0x01, 0x00000000 },
{ 0x0004d0, 16, 0x01, 0x00000000 },
{ 0x000720, 16, 0x01, 0x00000000 },
{ 0x0008c0, 16, 0x01, 0x00000000 },
{ 0x000890, 16, 0x01, 0x00000000 },
{ 0x0008e0, 16, 0x01, 0x00000000 },
{ 0x0008a0, 16, 0x01, 0x00000000 },
{ 0x0008f0, 16, 0x01, 0x00000000 },
{ 0x00094c, 1, 0x01, 0x000000ff },
{ 0x00094d, 1, 0x01, 0xffffffff },
{ 0x00094e, 1, 0x01, 0x00000002 },
{ 0x0002ec, 1, 0x01, 0x00000001 },
{ 0x000303, 1, 0x01, 0x00000001 },
{ 0x0002e6, 1, 0x01, 0x00000001 },
{ 0x000466, 1, 0x01, 0x00000052 },
{ 0x000301, 1, 0x01, 0x3f800000 },
{ 0x000304, 1, 0x01, 0x30201000 },
{ 0x000305, 1, 0x01, 0x70605040 },
{ 0x000306, 1, 0x01, 0xb8a89888 },
{ 0x000307, 1, 0x01, 0xf8e8d8c8 },
{ 0x00030a, 1, 0x01, 0x00ffff00 },
{ 0x00030b, 1, 0x01, 0x0000001a },
{ 0x00030c, 1, 0x01, 0x00000001 },
{ 0x000318, 1, 0x01, 0x00000001 },
{ 0x000340, 1, 0x01, 0x00000000 },
{ 0x000375, 1, 0x01, 0x00000001 },
{ 0x000351, 1, 0x01, 0x00000100 },
{ 0x00037d, 1, 0x01, 0x00000006 },
{ 0x0003a0, 1, 0x01, 0x00000002 },
{ 0x0003aa, 1, 0x01, 0x00000001 },
{ 0x0003a9, 1, 0x01, 0x00000001 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000360, 1, 0x01, 0x00000040 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00001fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x003fffff },
{ 0x00037a, 1, 0x01, 0x00000012 },
{ 0x0005e0, 5, 0x01, 0x00000022 },
{ 0x000619, 1, 0x01, 0x00000003 },
{ 0x000811, 1, 0x01, 0x00000003 },
{ 0x000812, 1, 0x01, 0x00000004 },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000815, 1, 0x01, 0x0000000b },
{ 0x000800, 6, 0x01, 0x00000001 },
{ 0x000632, 1, 0x01, 0x00000001 },
{ 0x000633, 1, 0x01, 0x00000002 },
{ 0x000634, 1, 0x01, 0x00000003 },
{ 0x000635, 1, 0x01, 0x00000004 },
{ 0x000654, 1, 0x01, 0x3f800000 },
{ 0x000657, 1, 0x01, 0x3f800000 },
{ 0x000655, 2, 0x01, 0x3f800000 },
{ 0x0006cd, 1, 0x01, 0x3f800000 },
{ 0x0007f5, 1, 0x01, 0x3f800000 },
{ 0x0007dc, 1, 0x01, 0x39291909 },
{ 0x0007dd, 1, 0x01, 0x79695949 },
{ 0x0007de, 1, 0x01, 0xb9a99989 },
{ 0x0007df, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007e8, 1, 0x01, 0x00003210 },
{ 0x0007e9, 1, 0x01, 0x00007654 },
{ 0x0007ea, 1, 0x01, 0x00000098 },
{ 0x0007ec, 1, 0x01, 0x39291909 },
{ 0x0007ed, 1, 0x01, 0x79695949 },
{ 0x0007ee, 1, 0x01, 0xb9a99989 },
{ 0x0007ef, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007f0, 1, 0x01, 0x00003210 },
{ 0x0007f1, 1, 0x01, 0x00007654 },
{ 0x0007f2, 1, 0x01, 0x00000098 },
{ 0x0005a5, 1, 0x01, 0x00000001 },
{ 0x000980, 128, 0x01, 0x00000000 },
{ 0x000468, 1, 0x01, 0x00000004 },
{ 0x00046c, 1, 0x01, 0x00000001 },
{ 0x000470, 96, 0x01, 0x00000000 },
{ 0x000510, 16, 0x01, 0x3f800000 },
{ 0x000520, 1, 0x01, 0x000002b6 },
{ 0x000529, 1, 0x01, 0x00000001 },
{ 0x000530, 16, 0x01, 0xffff0000 },
{ 0x000585, 1, 0x01, 0x0000003f },
{ 0x000576, 1, 0x01, 0x00000003 },
{ 0x00057b, 1, 0x01, 0x00000059 },
{ 0x000586, 1, 0x01, 0x00000040 },
{ 0x000582, 2, 0x01, 0x00000080 },
{ 0x0005c2, 1, 0x01, 0x00000001 },
{ 0x000638, 2, 0x01, 0x00000001 },
{ 0x00063a, 1, 0x01, 0x00000002 },
{ 0x00063b, 2, 0x01, 0x00000001 },
{ 0x00063d, 1, 0x01, 0x00000002 },
{ 0x00063e, 1, 0x01, 0x00000001 },
{ 0x0008b8, 8, 0x01, 0x00000001 },
{ 0x000900, 8, 0x01, 0x00000001 },
{ 0x000908, 8, 0x01, 0x00000002 },
{ 0x000910, 16, 0x01, 0x00000001 },
{ 0x000920, 8, 0x01, 0x00000002 },
{ 0x000928, 8, 0x01, 0x00000001 },
{ 0x000648, 9, 0x01, 0x00000001 },
{ 0x000658, 1, 0x01, 0x0000000f },
{ 0x0007ff, 1, 0x01, 0x0000000a },
{ 0x00066a, 1, 0x01, 0x40000000 },
{ 0x00066b, 1, 0x01, 0x10000000 },
{ 0x00066c, 2, 0x01, 0xffff0000 },
{ 0x0007af, 2, 0x01, 0x00000008 },
{ 0x0007f6, 1, 0x01, 0x00000001 },
{ 0x0006b2, 1, 0x01, 0x00000055 },
{ 0x0007ad, 1, 0x01, 0x00000003 },
{ 0x000937, 1, 0x01, 0x00000001 },
{ 0x000971, 1, 0x01, 0x00000008 },
{ 0x000972, 1, 0x01, 0x00000040 },
{ 0x000973, 1, 0x01, 0x0000012c },
{ 0x00097c, 1, 0x01, 0x00000040 },
{ 0x000979, 1, 0x01, 0x00000003 },
{ 0x000975, 1, 0x01, 0x00000020 },
{ 0x000976, 1, 0x01, 0x00000001 },
{ 0x000977, 1, 0x01, 0x00000020 },
{ 0x000978, 1, 0x01, 0x00000001 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095e, 1, 0x01, 0x20164010 },
{ 0x00095f, 1, 0x01, 0x00000020 },
{ 0x00097d, 1, 0x01, 0x00000020 },
{ 0x000683, 1, 0x01, 0x00000006 },
{ 0x000685, 1, 0x01, 0x003fffff },
{ 0x000687, 1, 0x01, 0x00000c48 },
{ 0x0006a0, 1, 0x01, 0x00000005 },
{ 0x000840, 1, 0x01, 0x00300008 },
{ 0x000841, 1, 0x01, 0x04000080 },
{ 0x000842, 1, 0x01, 0x00300008 },
{ 0x000843, 1, 0x01, 0x04000080 },
{ 0x000818, 8, 0x01, 0x00000000 },
{ 0x000848, 16, 0x01, 0x00000000 },
{ 0x000738, 1, 0x01, 0x00000000 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ab, 1, 0x01, 0x00000002 },
{ 0x0006ac, 1, 0x01, 0x00000080 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x0006bb, 1, 0x01, 0x000000cf },
{ 0x0006ce, 1, 0x01, 0x2a712488 },
{ 0x000739, 1, 0x01, 0x4085c000 },
{ 0x00073a, 1, 0x01, 0x00000080 },
{ 0x000786, 1, 0x01, 0x80000100 },
{ 0x00073c, 1, 0x01, 0x00010100 },
{ 0x00073d, 1, 0x01, 0x02800000 },
{ 0x000787, 1, 0x01, 0x000000cf },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x000836, 1, 0x01, 0x00000001 },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x00080c, 1, 0x01, 0x00000002 },
{ 0x00080d, 2, 0x01, 0x00000100 },
{ 0x00080f, 1, 0x01, 0x00000001 },
{ 0x000823, 1, 0x01, 0x00000002 },
{ 0x000824, 2, 0x01, 0x00000100 },
{ 0x000826, 1, 0x01, 0x00000001 },
{ 0x00095d, 1, 0x01, 0x00000001 },
{ 0x00082b, 1, 0x01, 0x00000004 },
{ 0x000942, 1, 0x01, 0x00010001 },
{ 0x000943, 1, 0x01, 0x00000001 },
{ 0x000944, 1, 0x01, 0x00000022 },
{ 0x0007c5, 1, 0x01, 0x00010001 },
{ 0x000834, 1, 0x01, 0x00000001 },
{ 0x0007c7, 1, 0x01, 0x00000001 },
{ 0x00c1b0, 8, 0x01, 0x0000000f },
{ 0x00c1b8, 1, 0x01, 0x0fac6881 },
{ 0x00c1b9, 1, 0x01, 0x00fac688 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000002 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000014 },
{ 0x000351, 1, 0x01, 0x00000100 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095d, 1, 0x01, 0x00000001 },
{ 0x00082b, 1, 0x01, 0x00000004 },
{ 0x000942, 1, 0x01, 0x00010001 },
{ 0x000943, 1, 0x01, 0x00000001 },
{ 0x0007c5, 1, 0x01, 0x00010001 },
{ 0x000834, 1, 0x01, 0x00000001 },
{ 0x0007c7, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000001 },
{ 0x00080c, 1, 0x01, 0x00000002 },
{ 0x00080d, 2, 0x01, 0x00000100 },
{ 0x00080f, 1, 0x01, 0x00000001 },
{ 0x000823, 1, 0x01, 0x00000002 },
{ 0x000824, 2, 0x01, 0x00000100 },
{ 0x000826, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
nvc8_grctx_pack_icmd[] = {
{ nvc8_grctx_init_icmd_0 },
{}
};
const struct nvc0_graph_init
nvc8_grctx_init_9197_0[] = {
{ 0x0002e4, 1, 0x04, 0x0000b001 },
{}
};
const struct nvc0_graph_init
nvc8_grctx_init_9297_0[] = {
{ 0x003400, 128, 0x04, 0x00000000 },
{ 0x00036c, 2, 0x04, 0x00000000 },
{ 0x0007a4, 2, 0x04, 0x00000000 },
{ 0x000374, 1, 0x04, 0x00000000 },
{ 0x000378, 1, 0x04, 0x00000020 },
{}
};
static const struct nvc0_graph_pack
nvc8_grctx_pack_mthd[] = {
{ nvc1_grctx_init_9097_0, 0x9097 },
{ nvc8_grctx_init_9197_0, 0x9197 },
{ nvc8_grctx_init_9297_0, 0x9297 },
{ nvc0_grctx_init_902d_0, 0x902d },
{ nvc0_grctx_init_9039_0, 0x9039 },
{ nvc0_grctx_init_90c0_0, 0x90c0 },
{}
};
static const struct nvc0_graph_init
nvc8_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x0006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
{ 0x418830, 1, 0x04, 0x00000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x20100000 },
{}
};
static const struct nvc0_graph_pack
nvc8_grctx_pack_gpc[] = {
{ nvc0_grctx_init_gpc_unk_0 },
{ nvc0_grctx_init_prop_0 },
{ nvc0_grctx_init_gpc_unk_1 },
{ nvc8_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nvc0_grctx_init_crstr_0 },
{ nvc0_grctx_init_gpm_0 },
{ nvc0_grctx_init_gcc_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
struct nouveau_oclass *
nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xc8),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nvc0_grctx_generate_main,
.mods = nvc0_grctx_generate_mods,
.unkn = nvc0_grctx_generate_unkn,
.hub = nvc0_grctx_pack_hub,
.gpc = nvc8_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nvc0_grctx_pack_tpc,
.icmd = nvc8_grctx_pack_icmd,
.mthd = nvc8_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,275 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
nvd7_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180324 },
{ 0x405834, 1, 0x04, 0x08000000 },
{ 0x405838, 1, 0x04, 0x00000000 },
{ 0x405854, 1, 0x04, 0x00000000 },
{ 0x405870, 4, 0x04, 0x00000001 },
{ 0x405a00, 2, 0x04, 0x00000000 },
{ 0x405a18, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvd7_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
{ 0x4064ac, 1, 0x04, 0x00003fff },
{ 0x4064b4, 3, 0x04, 0x00000000 },
{ 0x4064c0, 1, 0x04, 0x801a0078 },
{ 0x4064c4, 1, 0x04, 0x00c9ffff },
{ 0x4064d0, 8, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
nvd7_grctx_pack_hub[] = {
{ nvc0_grctx_init_main_0 },
{ nvd9_grctx_init_fe_0 },
{ nvc0_grctx_init_pri_0 },
{ nvc0_grctx_init_memfmt_0 },
{ nvd7_grctx_init_ds_0 },
{ nvd7_grctx_init_pd_0 },
{ nvc0_grctx_init_rstr2d_0 },
{ nvc0_grctx_init_scc_0 },
{ nvd9_grctx_init_be_0 },
{}
};
static const struct nvc0_graph_init
nvd7_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
{ 0x418830, 1, 0x04, 0x10000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x20100018 },
{}
};
static const struct nvc0_graph_pack
nvd7_grctx_pack_gpc[] = {
{ nvc0_grctx_init_gpc_unk_0 },
{ nvd9_grctx_init_prop_0 },
{ nvd9_grctx_init_gpc_unk_1 },
{ nvd7_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nvd9_grctx_init_crstr_0 },
{ nvc1_grctx_init_gpm_0 },
{ nvc0_grctx_init_gcc_0 },
{}
};
const struct nvc0_graph_init
nvd7_grctx_init_pe_0[] = {
{ 0x419848, 1, 0x04, 0x00000000 },
{ 0x419864, 1, 0x04, 0x00000129 },
{ 0x419888, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvd7_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
{ 0x419a0c, 1, 0x04, 0x00020000 },
{ 0x419a10, 1, 0x04, 0x00000000 },
{ 0x419a14, 1, 0x04, 0x00000200 },
{ 0x419a1c, 1, 0x04, 0x00008000 },
{ 0x419a20, 1, 0x04, 0x00000800 },
{ 0x419ac4, 1, 0x04, 0x0017f440 },
{}
};
static const struct nvc0_graph_init
nvd7_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000000a },
{ 0x419c04, 1, 0x04, 0x00000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
{ 0x419c20, 1, 0x04, 0x00000000 },
{ 0x419c24, 1, 0x04, 0x00084210 },
{ 0x419c28, 1, 0x04, 0x3efbefbe },
{}
};
static const struct nvc0_graph_pack
nvd7_grctx_pack_tpc[] = {
{ nvd7_grctx_init_pe_0 },
{ nvd7_grctx_init_tex_0 },
{ nvd7_grctx_init_mpc_0 },
{ nvc4_grctx_init_l1c_0 },
{ nvd9_grctx_init_sm_0 },
{}
};
static const struct nvc0_graph_init
nvd7_grctx_init_pes_0[] = {
{ 0x41be24, 1, 0x04, 0x00000002 },
{}
};
static const struct nvc0_graph_init
nvd7_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x12180000 },
{ 0x41bec4, 1, 0x04, 0x00003fff },
{ 0x41bee4, 1, 0x04, 0x03240218 },
{}
};
const struct nvc0_graph_init
nvd7_grctx_init_wwdx_0[] = {
{ 0x41bf00, 1, 0x04, 0x0a418820 },
{ 0x41bf04, 1, 0x04, 0x062080e6 },
{ 0x41bf08, 1, 0x04, 0x020398a4 },
{ 0x41bf0c, 1, 0x04, 0x0e629062 },
{ 0x41bf10, 1, 0x04, 0x0a418820 },
{ 0x41bf14, 1, 0x04, 0x000000e6 },
{ 0x41bfd0, 1, 0x04, 0x00900103 },
{ 0x41bfe0, 1, 0x04, 0x00400001 },
{ 0x41bfe4, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
nvd7_grctx_pack_ppc[] = {
{ nvd7_grctx_init_pes_0 },
{ nvd7_grctx_init_cbm_0 },
{ nvd7_grctx_init_wwdx_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
static void
nvd7_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
u32 magic[GPC_MAX][2];
u32 offset;
int gpc;
mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
mmio_list(0x40800c, 0x00000000, 8, 1);
mmio_list(0x408010, 0x80000000, 0, 0);
mmio_list(0x419004, 0x00000000, 8, 1);
mmio_list(0x419008, 0x00000000, 0, 0);
mmio_list(0x408004, 0x00000000, 8, 0);
mmio_list(0x408008, 0x80000018, 0, 0);
mmio_list(0x418808, 0x00000000, 8, 0);
mmio_list(0x41880c, 0x80000018, 0, 0);
mmio_list(0x418810, 0x80000000, 12, 2);
mmio_list(0x419848, 0x10000000, 12, 2);
mmio_list(0x405830, 0x02180324, 0, 0);
mmio_list(0x4064c4, 0x00c9ffff, 0, 0);
for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
u16 magic0 = 0x0218 * priv->tpc_nr[gpc];
u16 magic1 = 0x0324 * priv->tpc_nr[gpc];
magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset;
magic[gpc][1] = 0x00000000 | (magic1 << 16);
offset += 0x0324 * priv->tpc_nr[gpc];
}
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
offset += 0x07ff * priv->tpc_nr[gpc];
}
mmio_list(0x17e91c, 0x03060609, 0, 0); /* different from kepler */
}
void
nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
int i;
nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
nvc0_graph_mmio(priv, oclass->hub);
nvc0_graph_mmio(priv, oclass->gpc);
nvc0_graph_mmio(priv, oclass->zcull);
nvc0_graph_mmio(priv, oclass->tpc);
nvc0_graph_mmio(priv, oclass->ppc);
nv_wr32(priv, 0x404154, 0x00000000);
oclass->mods(priv, info);
oclass->unkn(priv);
nvc0_grctx_generate_tpcid(priv);
nvc0_grctx_generate_r406028(priv);
nvc0_grctx_generate_r4060a8(priv);
nve4_grctx_generate_r418bb8(priv);
nvc0_grctx_generate_r406800(priv);
for (i = 0; i < 8; i++)
nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
nvc0_graph_icmd(priv, oclass->icmd);
nv_wr32(priv, 0x404154, 0x00000400);
nvc0_graph_mthd(priv, oclass->mthd);
nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
}
struct nouveau_oclass *
nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xd7),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nvd7_grctx_generate_main,
.mods = nvd7_grctx_generate_mods,
.unkn = nve4_grctx_generate_unkn,
.hub = nvd7_grctx_pack_hub,
.gpc = nvd7_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nvd7_grctx_pack_tpc,
.ppc = nvd7_grctx_pack_ppc,
.icmd = nvd9_grctx_pack_icmd,
.mthd = nvd9_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,522 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
nvd9_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
{ 0x00003d, 1, 0x01, 0x00000001 },
{ 0x0000e8, 8, 0x01, 0x00000400 },
{ 0x000078, 8, 0x01, 0x00000300 },
{ 0x000050, 1, 0x01, 0x00000011 },
{ 0x000058, 8, 0x01, 0x00000008 },
{ 0x000208, 8, 0x01, 0x00000001 },
{ 0x000081, 1, 0x01, 0x00000001 },
{ 0x000085, 1, 0x01, 0x00000004 },
{ 0x000088, 1, 0x01, 0x00000400 },
{ 0x000090, 1, 0x01, 0x00000300 },
{ 0x000098, 1, 0x01, 0x00001001 },
{ 0x0000e3, 1, 0x01, 0x00000001 },
{ 0x0000da, 1, 0x01, 0x00000001 },
{ 0x0000f8, 1, 0x01, 0x00000003 },
{ 0x0000fa, 1, 0x01, 0x00000001 },
{ 0x00009f, 4, 0x01, 0x0000ffff },
{ 0x0000b1, 1, 0x01, 0x00000001 },
{ 0x0000b2, 40, 0x01, 0x00000000 },
{ 0x000210, 8, 0x01, 0x00000040 },
{ 0x000400, 24, 0x01, 0x00000040 },
{ 0x000218, 8, 0x01, 0x0000c080 },
{ 0x000440, 24, 0x01, 0x0000c080 },
{ 0x0000ad, 1, 0x01, 0x0000013e },
{ 0x0000e1, 1, 0x01, 0x00000010 },
{ 0x000290, 16, 0x01, 0x00000000 },
{ 0x0003b0, 16, 0x01, 0x00000000 },
{ 0x0002a0, 16, 0x01, 0x00000000 },
{ 0x000420, 16, 0x01, 0x00000000 },
{ 0x0002b0, 16, 0x01, 0x00000000 },
{ 0x000430, 16, 0x01, 0x00000000 },
{ 0x0002c0, 16, 0x01, 0x00000000 },
{ 0x0004d0, 16, 0x01, 0x00000000 },
{ 0x000720, 16, 0x01, 0x00000000 },
{ 0x0008c0, 16, 0x01, 0x00000000 },
{ 0x000890, 16, 0x01, 0x00000000 },
{ 0x0008e0, 16, 0x01, 0x00000000 },
{ 0x0008a0, 16, 0x01, 0x00000000 },
{ 0x0008f0, 16, 0x01, 0x00000000 },
{ 0x00094c, 1, 0x01, 0x000000ff },
{ 0x00094d, 1, 0x01, 0xffffffff },
{ 0x00094e, 1, 0x01, 0x00000002 },
{ 0x0002ec, 1, 0x01, 0x00000001 },
{ 0x000303, 1, 0x01, 0x00000001 },
{ 0x0002e6, 1, 0x01, 0x00000001 },
{ 0x000466, 1, 0x01, 0x00000052 },
{ 0x000301, 1, 0x01, 0x3f800000 },
{ 0x000304, 1, 0x01, 0x30201000 },
{ 0x000305, 1, 0x01, 0x70605040 },
{ 0x000306, 1, 0x01, 0xb8a89888 },
{ 0x000307, 1, 0x01, 0xf8e8d8c8 },
{ 0x00030a, 1, 0x01, 0x00ffff00 },
{ 0x00030b, 1, 0x01, 0x0000001a },
{ 0x00030c, 1, 0x01, 0x00000001 },
{ 0x000318, 1, 0x01, 0x00000001 },
{ 0x000340, 1, 0x01, 0x00000000 },
{ 0x000375, 1, 0x01, 0x00000001 },
{ 0x000351, 1, 0x01, 0x00000100 },
{ 0x00037d, 1, 0x01, 0x00000006 },
{ 0x0003a0, 1, 0x01, 0x00000002 },
{ 0x0003aa, 1, 0x01, 0x00000001 },
{ 0x0003a9, 1, 0x01, 0x00000001 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000360, 1, 0x01, 0x00000040 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00001fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x003fffff },
{ 0x00037a, 1, 0x01, 0x00000012 },
{ 0x0005e0, 5, 0x01, 0x00000022 },
{ 0x000619, 1, 0x01, 0x00000003 },
{ 0x000811, 1, 0x01, 0x00000003 },
{ 0x000812, 1, 0x01, 0x00000004 },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000815, 1, 0x01, 0x0000000b },
{ 0x000800, 6, 0x01, 0x00000001 },
{ 0x000632, 1, 0x01, 0x00000001 },
{ 0x000633, 1, 0x01, 0x00000002 },
{ 0x000634, 1, 0x01, 0x00000003 },
{ 0x000635, 1, 0x01, 0x00000004 },
{ 0x000654, 1, 0x01, 0x3f800000 },
{ 0x000657, 1, 0x01, 0x3f800000 },
{ 0x000655, 2, 0x01, 0x3f800000 },
{ 0x0006cd, 1, 0x01, 0x3f800000 },
{ 0x0007f5, 1, 0x01, 0x3f800000 },
{ 0x0007dc, 1, 0x01, 0x39291909 },
{ 0x0007dd, 1, 0x01, 0x79695949 },
{ 0x0007de, 1, 0x01, 0xb9a99989 },
{ 0x0007df, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007e8, 1, 0x01, 0x00003210 },
{ 0x0007e9, 1, 0x01, 0x00007654 },
{ 0x0007ea, 1, 0x01, 0x00000098 },
{ 0x0007ec, 1, 0x01, 0x39291909 },
{ 0x0007ed, 1, 0x01, 0x79695949 },
{ 0x0007ee, 1, 0x01, 0xb9a99989 },
{ 0x0007ef, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007f0, 1, 0x01, 0x00003210 },
{ 0x0007f1, 1, 0x01, 0x00007654 },
{ 0x0007f2, 1, 0x01, 0x00000098 },
{ 0x0005a5, 1, 0x01, 0x00000001 },
{ 0x000980, 128, 0x01, 0x00000000 },
{ 0x000468, 1, 0x01, 0x00000004 },
{ 0x00046c, 1, 0x01, 0x00000001 },
{ 0x000470, 96, 0x01, 0x00000000 },
{ 0x000510, 16, 0x01, 0x3f800000 },
{ 0x000520, 1, 0x01, 0x000002b6 },
{ 0x000529, 1, 0x01, 0x00000001 },
{ 0x000530, 16, 0x01, 0xffff0000 },
{ 0x000585, 1, 0x01, 0x0000003f },
{ 0x000576, 1, 0x01, 0x00000003 },
{ 0x00057b, 1, 0x01, 0x00000059 },
{ 0x000586, 1, 0x01, 0x00000040 },
{ 0x000582, 2, 0x01, 0x00000080 },
{ 0x0005c2, 1, 0x01, 0x00000001 },
{ 0x000638, 2, 0x01, 0x00000001 },
{ 0x00063a, 1, 0x01, 0x00000002 },
{ 0x00063b, 2, 0x01, 0x00000001 },
{ 0x00063d, 1, 0x01, 0x00000002 },
{ 0x00063e, 1, 0x01, 0x00000001 },
{ 0x0008b8, 8, 0x01, 0x00000001 },
{ 0x000900, 8, 0x01, 0x00000001 },
{ 0x000908, 8, 0x01, 0x00000002 },
{ 0x000910, 16, 0x01, 0x00000001 },
{ 0x000920, 8, 0x01, 0x00000002 },
{ 0x000928, 8, 0x01, 0x00000001 },
{ 0x000648, 9, 0x01, 0x00000001 },
{ 0x000658, 1, 0x01, 0x0000000f },
{ 0x0007ff, 1, 0x01, 0x0000000a },
{ 0x00066a, 1, 0x01, 0x40000000 },
{ 0x00066b, 1, 0x01, 0x10000000 },
{ 0x00066c, 2, 0x01, 0xffff0000 },
{ 0x0007af, 2, 0x01, 0x00000008 },
{ 0x0007f6, 1, 0x01, 0x00000001 },
{ 0x0006b2, 1, 0x01, 0x00000055 },
{ 0x0007ad, 1, 0x01, 0x00000003 },
{ 0x000937, 1, 0x01, 0x00000001 },
{ 0x000971, 1, 0x01, 0x00000008 },
{ 0x000972, 1, 0x01, 0x00000040 },
{ 0x000973, 1, 0x01, 0x0000012c },
{ 0x00097c, 1, 0x01, 0x00000040 },
{ 0x000979, 1, 0x01, 0x00000003 },
{ 0x000975, 1, 0x01, 0x00000020 },
{ 0x000976, 1, 0x01, 0x00000001 },
{ 0x000977, 1, 0x01, 0x00000020 },
{ 0x000978, 1, 0x01, 0x00000001 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095e, 1, 0x01, 0x20164010 },
{ 0x00095f, 1, 0x01, 0x00000020 },
{ 0x00097d, 1, 0x01, 0x00000020 },
{ 0x000683, 1, 0x01, 0x00000006 },
{ 0x000685, 1, 0x01, 0x003fffff },
{ 0x000687, 1, 0x01, 0x00000c48 },
{ 0x0006a0, 1, 0x01, 0x00000005 },
{ 0x000840, 1, 0x01, 0x00300008 },
{ 0x000841, 1, 0x01, 0x04000080 },
{ 0x000842, 1, 0x01, 0x00300008 },
{ 0x000843, 1, 0x01, 0x04000080 },
{ 0x000818, 8, 0x01, 0x00000000 },
{ 0x000848, 16, 0x01, 0x00000000 },
{ 0x000738, 1, 0x01, 0x00000000 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ab, 1, 0x01, 0x00000002 },
{ 0x0006ac, 1, 0x01, 0x00000080 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x0006bb, 1, 0x01, 0x000000cf },
{ 0x0006ce, 1, 0x01, 0x2a712488 },
{ 0x000739, 1, 0x01, 0x4085c000 },
{ 0x00073a, 1, 0x01, 0x00000080 },
{ 0x000786, 1, 0x01, 0x80000100 },
{ 0x00073c, 1, 0x01, 0x00010100 },
{ 0x00073d, 1, 0x01, 0x02800000 },
{ 0x000787, 1, 0x01, 0x000000cf },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x000836, 1, 0x01, 0x00000001 },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x00080c, 1, 0x01, 0x00000002 },
{ 0x00080d, 2, 0x01, 0x00000100 },
{ 0x00080f, 1, 0x01, 0x00000001 },
{ 0x000823, 1, 0x01, 0x00000002 },
{ 0x000824, 2, 0x01, 0x00000100 },
{ 0x000826, 1, 0x01, 0x00000001 },
{ 0x00095d, 1, 0x01, 0x00000001 },
{ 0x00082b, 1, 0x01, 0x00000004 },
{ 0x000942, 1, 0x01, 0x00010001 },
{ 0x000943, 1, 0x01, 0x00000001 },
{ 0x000944, 1, 0x01, 0x00000022 },
{ 0x0007c5, 1, 0x01, 0x00010001 },
{ 0x000834, 1, 0x01, 0x00000001 },
{ 0x0007c7, 1, 0x01, 0x00000001 },
{ 0x00c1b0, 8, 0x01, 0x0000000f },
{ 0x00c1b8, 1, 0x01, 0x0fac6881 },
{ 0x00c1b9, 1, 0x01, 0x00fac688 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000002 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000014 },
{ 0x000351, 1, 0x01, 0x00000100 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095d, 1, 0x01, 0x00000001 },
{ 0x00082b, 1, 0x01, 0x00000004 },
{ 0x000942, 1, 0x01, 0x00010001 },
{ 0x000943, 1, 0x01, 0x00000001 },
{ 0x0007c5, 1, 0x01, 0x00010001 },
{ 0x000834, 1, 0x01, 0x00000001 },
{ 0x0007c7, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000001 },
{ 0x00080c, 1, 0x01, 0x00000002 },
{ 0x00080d, 2, 0x01, 0x00000100 },
{ 0x00080f, 1, 0x01, 0x00000001 },
{ 0x000823, 1, 0x01, 0x00000002 },
{ 0x000824, 2, 0x01, 0x00000100 },
{ 0x000826, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{}
};
const struct nvc0_graph_pack
nvd9_grctx_pack_icmd[] = {
{ nvd9_grctx_init_icmd_0 },
{}
};
static const struct nvc0_graph_init
nvd9_grctx_init_90c0_0[] = {
{ 0x002700, 8, 0x20, 0x00000000 },
{ 0x002704, 8, 0x20, 0x00000000 },
{ 0x002708, 8, 0x20, 0x00000000 },
{ 0x00270c, 8, 0x20, 0x00000000 },
{ 0x002710, 8, 0x20, 0x00014000 },
{ 0x002714, 8, 0x20, 0x00000040 },
{ 0x00030c, 1, 0x04, 0x00000001 },
{ 0x001944, 1, 0x04, 0x00000000 },
{ 0x000758, 1, 0x04, 0x00000100 },
{ 0x0002c4, 1, 0x04, 0x00000000 },
{ 0x000790, 5, 0x04, 0x00000000 },
{ 0x00077c, 1, 0x04, 0x00000000 },
{ 0x000204, 3, 0x04, 0x00000000 },
{ 0x000214, 1, 0x04, 0x00000000 },
{ 0x00024c, 1, 0x04, 0x00000000 },
{ 0x000d94, 1, 0x04, 0x00000001 },
{ 0x001608, 2, 0x04, 0x00000000 },
{ 0x001664, 1, 0x04, 0x00000000 },
{}
};
const struct nvc0_graph_pack
nvd9_grctx_pack_mthd[] = {
{ nvc1_grctx_init_9097_0, 0x9097 },
{ nvc8_grctx_init_9197_0, 0x9197 },
{ nvc8_grctx_init_9297_0, 0x9297 },
{ nvc0_grctx_init_902d_0, 0x902d },
{ nvc0_grctx_init_9039_0, 0x9039 },
{ nvd9_grctx_init_90c0_0, 0x90c0 },
{}
};
const struct nvc0_graph_init
nvd9_grctx_init_fe_0[] = {
{ 0x404004, 10, 0x04, 0x00000000 },
{ 0x404044, 1, 0x04, 0x00000000 },
{ 0x404094, 13, 0x04, 0x00000000 },
{ 0x4040c8, 1, 0x04, 0xf0000087 },
{ 0x4040d0, 6, 0x04, 0x00000000 },
{ 0x4040e8, 1, 0x04, 0x00001000 },
{ 0x4040f8, 1, 0x04, 0x00000000 },
{ 0x404130, 2, 0x04, 0x00000000 },
{ 0x404138, 1, 0x04, 0x20000040 },
{ 0x404150, 1, 0x04, 0x0000002e },
{ 0x404154, 1, 0x04, 0x00000400 },
{ 0x404158, 1, 0x04, 0x00000200 },
{ 0x404164, 1, 0x04, 0x00000055 },
{ 0x404168, 1, 0x04, 0x00000000 },
{ 0x404178, 2, 0x04, 0x00000000 },
{ 0x404200, 8, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvd9_grctx_init_ds_0[] = {
{ 0x405800, 1, 0x04, 0x0f8000bf },
{ 0x405830, 1, 0x04, 0x02180218 },
{ 0x405834, 1, 0x04, 0x08000000 },
{ 0x405838, 1, 0x04, 0x00000000 },
{ 0x405854, 1, 0x04, 0x00000000 },
{ 0x405870, 4, 0x04, 0x00000001 },
{ 0x405a00, 2, 0x04, 0x00000000 },
{ 0x405a18, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvd9_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x000103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
{ 0x4064ac, 1, 0x04, 0x00003fff },
{ 0x4064b4, 3, 0x04, 0x00000000 },
{ 0x4064c0, 1, 0x04, 0x80140078 },
{ 0x4064c4, 1, 0x04, 0x0086ffff },
{}
};
const struct nvc0_graph_init
nvd9_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x02802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1043e005 },
{ 0x408900, 1, 0x04, 0x3080b801 },
{ 0x408904, 1, 0x04, 0x62000001 },
{ 0x408908, 1, 0x04, 0x00c8102f },
{ 0x408980, 1, 0x04, 0x0000011d },
{}
};
static const struct nvc0_graph_pack
nvd9_grctx_pack_hub[] = {
{ nvc0_grctx_init_main_0 },
{ nvd9_grctx_init_fe_0 },
{ nvc0_grctx_init_pri_0 },
{ nvc0_grctx_init_memfmt_0 },
{ nvd9_grctx_init_ds_0 },
{ nvd9_grctx_init_pd_0 },
{ nvc0_grctx_init_rstr2d_0 },
{ nvc0_grctx_init_scc_0 },
{ nvd9_grctx_init_be_0 },
{}
};
const struct nvc0_graph_init
nvd9_grctx_init_prop_0[] = {
{ 0x418400, 1, 0x04, 0x38004e00 },
{ 0x418404, 1, 0x04, 0x71e0ffff },
{ 0x41840c, 1, 0x04, 0x00001008 },
{ 0x418410, 1, 0x04, 0x0fff0fff },
{ 0x418414, 1, 0x04, 0x02200fff },
{ 0x418450, 6, 0x04, 0x00000000 },
{ 0x418468, 1, 0x04, 0x00000001 },
{ 0x41846c, 2, 0x04, 0x00000000 },
{}
};
const struct nvc0_graph_init
nvd9_grctx_init_gpc_unk_1[] = {
{ 0x418600, 1, 0x04, 0x0000001f },
{ 0x418684, 1, 0x04, 0x0000000f },
{ 0x418700, 1, 0x04, 0x00000002 },
{ 0x418704, 1, 0x04, 0x00000080 },
{ 0x418708, 3, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_init
nvd9_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 3, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00008442 },
{ 0x418830, 1, 0x04, 0x10000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x20100008 },
{}
};
const struct nvc0_graph_init
nvd9_grctx_init_crstr_0[] = {
{ 0x418b00, 1, 0x04, 0x00000006 },
{ 0x418b08, 1, 0x04, 0x0a418820 },
{ 0x418b0c, 1, 0x04, 0x062080e6 },
{ 0x418b10, 1, 0x04, 0x020398a4 },
{ 0x418b14, 1, 0x04, 0x0e629062 },
{ 0x418b18, 1, 0x04, 0x0a418820 },
{ 0x418b1c, 1, 0x04, 0x000000e6 },
{ 0x418bb8, 1, 0x04, 0x00000103 },
{}
};
static const struct nvc0_graph_pack
nvd9_grctx_pack_gpc[] = {
{ nvc0_grctx_init_gpc_unk_0 },
{ nvd9_grctx_init_prop_0 },
{ nvd9_grctx_init_gpc_unk_1 },
{ nvd9_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nvd9_grctx_init_crstr_0 },
{ nvc1_grctx_init_gpm_0 },
{ nvc0_grctx_init_gcc_0 },
{}
};
static const struct nvc0_graph_init
nvd9_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000001f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000023 },
{ 0x419a0c, 1, 0x04, 0x00020000 },
{ 0x419a10, 1, 0x04, 0x00000000 },
{ 0x419a14, 1, 0x04, 0x00000200 },
{ 0x419a1c, 1, 0x04, 0x00000000 },
{ 0x419a20, 1, 0x04, 0x00000800 },
{ 0x419ac4, 1, 0x04, 0x0017f440 },
{}
};
static const struct nvc0_graph_init
nvd9_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000000a },
{ 0x419c04, 1, 0x04, 0x00000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
{ 0x419c20, 1, 0x04, 0x00000000 },
{ 0x419c24, 1, 0x04, 0x00084210 },
{ 0x419c28, 1, 0x04, 0x3cf3cf3c },
{}
};
const struct nvc0_graph_init
nvd9_grctx_init_sm_0[] = {
{ 0x419e04, 3, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00000002 },
{ 0x419e44, 1, 0x04, 0x001beff2 },
{ 0x419e48, 1, 0x04, 0x00000000 },
{ 0x419e4c, 1, 0x04, 0x0000000f },
{ 0x419e50, 17, 0x04, 0x00000000 },
{ 0x419e98, 1, 0x04, 0x00000000 },
{ 0x419ee0, 1, 0x04, 0x00010110 },
{ 0x419f30, 11, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
nvd9_grctx_pack_tpc[] = {
{ nvc1_grctx_init_pe_0 },
{ nvd9_grctx_init_tex_0 },
{ nvc1_grctx_init_wwdx_0 },
{ nvd9_grctx_init_mpc_0 },
{ nvc4_grctx_init_l1c_0 },
{ nvc1_grctx_init_tpccs_0 },
{ nvd9_grctx_init_sm_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
struct nouveau_oclass *
nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xd9),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nvc0_grctx_generate_main,
.mods = nvc1_grctx_generate_mods,
.unkn = nvc1_grctx_generate_unkn,
.hub = nvd9_grctx_pack_hub,
.gpc = nvd9_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nvd9_grctx_pack_tpc,
.icmd = nvd9_grctx_pack_icmd,
.mthd = nvd9_grctx_pack_mthd,
}.base;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,885 @@
/*
* 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 "ctxnvc0.h"
/*******************************************************************************
* PGRAPH context register lists
******************************************************************************/
static const struct nvc0_graph_init
nvf0_grctx_init_icmd_0[] = {
{ 0x001000, 1, 0x01, 0x00000004 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x0000a9, 1, 0x01, 0x0000ffff },
{ 0x000038, 1, 0x01, 0x0fac6881 },
{ 0x00003d, 1, 0x01, 0x00000001 },
{ 0x0000e8, 8, 0x01, 0x00000400 },
{ 0x000078, 8, 0x01, 0x00000300 },
{ 0x000050, 1, 0x01, 0x00000011 },
{ 0x000058, 8, 0x01, 0x00000008 },
{ 0x000208, 8, 0x01, 0x00000001 },
{ 0x000081, 1, 0x01, 0x00000001 },
{ 0x000085, 1, 0x01, 0x00000004 },
{ 0x000088, 1, 0x01, 0x00000400 },
{ 0x000090, 1, 0x01, 0x00000300 },
{ 0x000098, 1, 0x01, 0x00001001 },
{ 0x0000e3, 1, 0x01, 0x00000001 },
{ 0x0000da, 1, 0x01, 0x00000001 },
{ 0x0000f8, 1, 0x01, 0x00000003 },
{ 0x0000fa, 1, 0x01, 0x00000001 },
{ 0x00009f, 4, 0x01, 0x0000ffff },
{ 0x0000b1, 1, 0x01, 0x00000001 },
{ 0x0000ad, 1, 0x01, 0x0000013e },
{ 0x0000e1, 1, 0x01, 0x00000010 },
{ 0x000290, 16, 0x01, 0x00000000 },
{ 0x0003b0, 16, 0x01, 0x00000000 },
{ 0x0002a0, 16, 0x01, 0x00000000 },
{ 0x000420, 16, 0x01, 0x00000000 },
{ 0x0002b0, 16, 0x01, 0x00000000 },
{ 0x000430, 16, 0x01, 0x00000000 },
{ 0x0002c0, 16, 0x01, 0x00000000 },
{ 0x0004d0, 16, 0x01, 0x00000000 },
{ 0x000720, 16, 0x01, 0x00000000 },
{ 0x0008c0, 16, 0x01, 0x00000000 },
{ 0x000890, 16, 0x01, 0x00000000 },
{ 0x0008e0, 16, 0x01, 0x00000000 },
{ 0x0008a0, 16, 0x01, 0x00000000 },
{ 0x0008f0, 16, 0x01, 0x00000000 },
{ 0x00094c, 1, 0x01, 0x000000ff },
{ 0x00094d, 1, 0x01, 0xffffffff },
{ 0x00094e, 1, 0x01, 0x00000002 },
{ 0x0002ec, 1, 0x01, 0x00000001 },
{ 0x0002f2, 2, 0x01, 0x00000001 },
{ 0x0002f5, 1, 0x01, 0x00000001 },
{ 0x0002f7, 1, 0x01, 0x00000001 },
{ 0x000303, 1, 0x01, 0x00000001 },
{ 0x0002e6, 1, 0x01, 0x00000001 },
{ 0x000466, 1, 0x01, 0x00000052 },
{ 0x000301, 1, 0x01, 0x3f800000 },
{ 0x000304, 1, 0x01, 0x30201000 },
{ 0x000305, 1, 0x01, 0x70605040 },
{ 0x000306, 1, 0x01, 0xb8a89888 },
{ 0x000307, 1, 0x01, 0xf8e8d8c8 },
{ 0x00030a, 1, 0x01, 0x00ffff00 },
{ 0x00030b, 1, 0x01, 0x0000001a },
{ 0x00030c, 1, 0x01, 0x00000001 },
{ 0x000318, 1, 0x01, 0x00000001 },
{ 0x000340, 1, 0x01, 0x00000000 },
{ 0x000375, 1, 0x01, 0x00000001 },
{ 0x00037d, 1, 0x01, 0x00000006 },
{ 0x0003a0, 1, 0x01, 0x00000002 },
{ 0x0003aa, 1, 0x01, 0x00000001 },
{ 0x0003a9, 1, 0x01, 0x00000001 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000383, 1, 0x01, 0x00000011 },
{ 0x000360, 1, 0x01, 0x00000040 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00000fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x000fffff },
{ 0x00037a, 1, 0x01, 0x00000012 },
{ 0x000619, 1, 0x01, 0x00000003 },
{ 0x000811, 1, 0x01, 0x00000003 },
{ 0x000812, 1, 0x01, 0x00000004 },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000815, 1, 0x01, 0x0000000b },
{ 0x000800, 6, 0x01, 0x00000001 },
{ 0x000632, 1, 0x01, 0x00000001 },
{ 0x000633, 1, 0x01, 0x00000002 },
{ 0x000634, 1, 0x01, 0x00000003 },
{ 0x000635, 1, 0x01, 0x00000004 },
{ 0x000654, 1, 0x01, 0x3f800000 },
{ 0x000657, 1, 0x01, 0x3f800000 },
{ 0x000655, 2, 0x01, 0x3f800000 },
{ 0x0006cd, 1, 0x01, 0x3f800000 },
{ 0x0007f5, 1, 0x01, 0x3f800000 },
{ 0x0007dc, 1, 0x01, 0x39291909 },
{ 0x0007dd, 1, 0x01, 0x79695949 },
{ 0x0007de, 1, 0x01, 0xb9a99989 },
{ 0x0007df, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007e8, 1, 0x01, 0x00003210 },
{ 0x0007e9, 1, 0x01, 0x00007654 },
{ 0x0007ea, 1, 0x01, 0x00000098 },
{ 0x0007ec, 1, 0x01, 0x39291909 },
{ 0x0007ed, 1, 0x01, 0x79695949 },
{ 0x0007ee, 1, 0x01, 0xb9a99989 },
{ 0x0007ef, 1, 0x01, 0xf9e9d9c9 },
{ 0x0007f0, 1, 0x01, 0x00003210 },
{ 0x0007f1, 1, 0x01, 0x00007654 },
{ 0x0007f2, 1, 0x01, 0x00000098 },
{ 0x0005a5, 1, 0x01, 0x00000001 },
{ 0x000980, 128, 0x01, 0x00000000 },
{ 0x000468, 1, 0x01, 0x00000004 },
{ 0x00046c, 1, 0x01, 0x00000001 },
{ 0x000470, 96, 0x01, 0x00000000 },
{ 0x000510, 16, 0x01, 0x3f800000 },
{ 0x000520, 1, 0x01, 0x000002b6 },
{ 0x000529, 1, 0x01, 0x00000001 },
{ 0x000530, 16, 0x01, 0xffff0000 },
{ 0x000585, 1, 0x01, 0x0000003f },
{ 0x000576, 1, 0x01, 0x00000003 },
{ 0x00057b, 1, 0x01, 0x00000059 },
{ 0x000586, 1, 0x01, 0x00000040 },
{ 0x000582, 2, 0x01, 0x00000080 },
{ 0x0005c2, 1, 0x01, 0x00000001 },
{ 0x000638, 2, 0x01, 0x00000001 },
{ 0x00063a, 1, 0x01, 0x00000002 },
{ 0x00063b, 2, 0x01, 0x00000001 },
{ 0x00063d, 1, 0x01, 0x00000002 },
{ 0x00063e, 1, 0x01, 0x00000001 },
{ 0x0008b8, 8, 0x01, 0x00000001 },
{ 0x000900, 8, 0x01, 0x00000001 },
{ 0x000908, 8, 0x01, 0x00000002 },
{ 0x000910, 16, 0x01, 0x00000001 },
{ 0x000920, 8, 0x01, 0x00000002 },
{ 0x000928, 8, 0x01, 0x00000001 },
{ 0x000662, 1, 0x01, 0x00000001 },
{ 0x000648, 9, 0x01, 0x00000001 },
{ 0x000658, 1, 0x01, 0x0000000f },
{ 0x0007ff, 1, 0x01, 0x0000000a },
{ 0x00066a, 1, 0x01, 0x40000000 },
{ 0x00066b, 1, 0x01, 0x10000000 },
{ 0x00066c, 2, 0x01, 0xffff0000 },
{ 0x0007af, 2, 0x01, 0x00000008 },
{ 0x0007f6, 1, 0x01, 0x00000001 },
{ 0x00080b, 1, 0x01, 0x00000002 },
{ 0x0006b2, 1, 0x01, 0x00000055 },
{ 0x0007ad, 1, 0x01, 0x00000003 },
{ 0x000937, 1, 0x01, 0x00000001 },
{ 0x000971, 1, 0x01, 0x00000008 },
{ 0x000972, 1, 0x01, 0x00000040 },
{ 0x000973, 1, 0x01, 0x0000012c },
{ 0x00097c, 1, 0x01, 0x00000040 },
{ 0x000979, 1, 0x01, 0x00000003 },
{ 0x000975, 1, 0x01, 0x00000020 },
{ 0x000976, 1, 0x01, 0x00000001 },
{ 0x000977, 1, 0x01, 0x00000020 },
{ 0x000978, 1, 0x01, 0x00000001 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x00095e, 1, 0x01, 0x20164010 },
{ 0x00095f, 1, 0x01, 0x00000020 },
{ 0x000a0d, 1, 0x01, 0x00000006 },
{ 0x00097d, 1, 0x01, 0x00000020 },
{ 0x000683, 1, 0x01, 0x00000006 },
{ 0x000685, 1, 0x01, 0x003fffff },
{ 0x000687, 1, 0x01, 0x003fffff },
{ 0x0006a0, 1, 0x01, 0x00000005 },
{ 0x000840, 1, 0x01, 0x00400008 },
{ 0x000841, 1, 0x01, 0x08000080 },
{ 0x000842, 1, 0x01, 0x00400008 },
{ 0x000843, 1, 0x01, 0x08000080 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ab, 1, 0x01, 0x00000002 },
{ 0x0006ac, 1, 0x01, 0x00000080 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x0006bb, 1, 0x01, 0x000000cf },
{ 0x0006ce, 1, 0x01, 0x2a712488 },
{ 0x000739, 1, 0x01, 0x4085c000 },
{ 0x00073a, 1, 0x01, 0x00000080 },
{ 0x000786, 1, 0x01, 0x80000100 },
{ 0x00073c, 1, 0x01, 0x00010100 },
{ 0x00073d, 1, 0x01, 0x02800000 },
{ 0x000787, 1, 0x01, 0x000000cf },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x000836, 1, 0x01, 0x00000001 },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x000a04, 1, 0x01, 0x000000ff },
{ 0x000a0b, 1, 0x01, 0x00000040 },
{ 0x00097f, 1, 0x01, 0x00000100 },
{ 0x000a02, 1, 0x01, 0x00000001 },
{ 0x000809, 1, 0x01, 0x00000007 },
{ 0x00c221, 1, 0x01, 0x00000040 },
{ 0x00c1b0, 8, 0x01, 0x0000000f },
{ 0x00c1b8, 1, 0x01, 0x0fac6881 },
{ 0x00c1b9, 1, 0x01, 0x00fac688 },
{ 0x00c401, 1, 0x01, 0x00000001 },
{ 0x00c402, 1, 0x01, 0x00010001 },
{ 0x00c403, 2, 0x01, 0x00000001 },
{ 0x00c40e, 1, 0x01, 0x00000020 },
{ 0x00c500, 1, 0x01, 0x00000003 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000002 },
{ 0x0006aa, 1, 0x01, 0x00000001 },
{ 0x0006ad, 2, 0x01, 0x00000100 },
{ 0x0006b1, 1, 0x01, 0x00000011 },
{ 0x00078c, 1, 0x01, 0x00000008 },
{ 0x000792, 1, 0x01, 0x00000001 },
{ 0x000794, 3, 0x01, 0x00000001 },
{ 0x000797, 1, 0x01, 0x000000cf },
{ 0x00079a, 1, 0x01, 0x00000002 },
{ 0x000833, 1, 0x01, 0x04444480 },
{ 0x0007a1, 1, 0x01, 0x00000001 },
{ 0x0007a3, 3, 0x01, 0x00000001 },
{ 0x000831, 1, 0x01, 0x00000004 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000008 },
{ 0x000039, 3, 0x01, 0x00000000 },
{ 0x000380, 1, 0x01, 0x00000001 },
{ 0x000366, 2, 0x01, 0x00000000 },
{ 0x000368, 1, 0x01, 0x00000fff },
{ 0x000370, 2, 0x01, 0x00000000 },
{ 0x000372, 1, 0x01, 0x000fffff },
{ 0x000813, 1, 0x01, 0x00000006 },
{ 0x000814, 1, 0x01, 0x00000008 },
{ 0x000957, 1, 0x01, 0x00000003 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x000a04, 1, 0x01, 0x000000ff },
{ 0x000a0b, 1, 0x01, 0x00000040 },
{ 0x00097f, 1, 0x01, 0x00000100 },
{ 0x000a02, 1, 0x01, 0x00000001 },
{ 0x000809, 1, 0x01, 0x00000007 },
{ 0x00c221, 1, 0x01, 0x00000040 },
{ 0x00c401, 1, 0x01, 0x00000001 },
{ 0x00c402, 1, 0x01, 0x00010001 },
{ 0x00c403, 2, 0x01, 0x00000001 },
{ 0x00c40e, 1, 0x01, 0x00000020 },
{ 0x00c500, 1, 0x01, 0x00000003 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{ 0x001000, 1, 0x01, 0x00000001 },
{ 0x000b07, 1, 0x01, 0x00000002 },
{ 0x000b08, 2, 0x01, 0x00000100 },
{ 0x000b0a, 1, 0x01, 0x00000001 },
{ 0x01e100, 1, 0x01, 0x00000001 },
{}
};
static const struct nvc0_graph_pack
nvf0_grctx_pack_icmd[] = {
{ nvf0_grctx_init_icmd_0 },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_a197_0[] = {
{ 0x000800, 8, 0x40, 0x00000000 },
{ 0x000804, 8, 0x40, 0x00000000 },
{ 0x000808, 8, 0x40, 0x00000400 },
{ 0x00080c, 8, 0x40, 0x00000300 },
{ 0x000810, 1, 0x04, 0x000000cf },
{ 0x000850, 7, 0x40, 0x00000000 },
{ 0x000814, 8, 0x40, 0x00000040 },
{ 0x000818, 8, 0x40, 0x00000001 },
{ 0x00081c, 8, 0x40, 0x00000000 },
{ 0x000820, 8, 0x40, 0x00000000 },
{ 0x001c00, 16, 0x10, 0x00000000 },
{ 0x001c04, 16, 0x10, 0x00000000 },
{ 0x001c08, 16, 0x10, 0x00000000 },
{ 0x001c0c, 16, 0x10, 0x00000000 },
{ 0x001d00, 16, 0x10, 0x00000000 },
{ 0x001d04, 16, 0x10, 0x00000000 },
{ 0x001d08, 16, 0x10, 0x00000000 },
{ 0x001d0c, 16, 0x10, 0x00000000 },
{ 0x001f00, 16, 0x08, 0x00000000 },
{ 0x001f04, 16, 0x08, 0x00000000 },
{ 0x001f80, 16, 0x08, 0x00000000 },
{ 0x001f84, 16, 0x08, 0x00000000 },
{ 0x002000, 1, 0x04, 0x00000000 },
{ 0x002040, 1, 0x04, 0x00000011 },
{ 0x002080, 1, 0x04, 0x00000020 },
{ 0x0020c0, 1, 0x04, 0x00000030 },
{ 0x002100, 1, 0x04, 0x00000040 },
{ 0x002140, 1, 0x04, 0x00000051 },
{ 0x00200c, 6, 0x40, 0x00000001 },
{ 0x002010, 1, 0x04, 0x00000000 },
{ 0x002050, 1, 0x04, 0x00000000 },
{ 0x002090, 1, 0x04, 0x00000001 },
{ 0x0020d0, 1, 0x04, 0x00000002 },
{ 0x002110, 1, 0x04, 0x00000003 },
{ 0x002150, 1, 0x04, 0x00000004 },
{ 0x000380, 4, 0x20, 0x00000000 },
{ 0x000384, 4, 0x20, 0x00000000 },
{ 0x000388, 4, 0x20, 0x00000000 },
{ 0x00038c, 4, 0x20, 0x00000000 },
{ 0x000700, 4, 0x10, 0x00000000 },
{ 0x000704, 4, 0x10, 0x00000000 },
{ 0x000708, 4, 0x10, 0x00000000 },
{ 0x002800, 128, 0x04, 0x00000000 },
{ 0x000a00, 16, 0x20, 0x00000000 },
{ 0x000a04, 16, 0x20, 0x00000000 },
{ 0x000a08, 16, 0x20, 0x00000000 },
{ 0x000a0c, 16, 0x20, 0x00000000 },
{ 0x000a10, 16, 0x20, 0x00000000 },
{ 0x000a14, 16, 0x20, 0x00000000 },
{ 0x000c00, 16, 0x10, 0x00000000 },
{ 0x000c04, 16, 0x10, 0x00000000 },
{ 0x000c08, 16, 0x10, 0x00000000 },
{ 0x000c0c, 16, 0x10, 0x3f800000 },
{ 0x000d00, 8, 0x08, 0xffff0000 },
{ 0x000d04, 8, 0x08, 0xffff0000 },
{ 0x000e00, 16, 0x10, 0x00000000 },
{ 0x000e04, 16, 0x10, 0xffff0000 },
{ 0x000e08, 16, 0x10, 0xffff0000 },
{ 0x000d40, 4, 0x08, 0x00000000 },
{ 0x000d44, 4, 0x08, 0x00000000 },
{ 0x001e00, 8, 0x20, 0x00000001 },
{ 0x001e04, 8, 0x20, 0x00000001 },
{ 0x001e08, 8, 0x20, 0x00000002 },
{ 0x001e0c, 8, 0x20, 0x00000001 },
{ 0x001e10, 8, 0x20, 0x00000001 },
{ 0x001e14, 8, 0x20, 0x00000002 },
{ 0x001e18, 8, 0x20, 0x00000001 },
{ 0x003400, 128, 0x04, 0x00000000 },
{ 0x00030c, 1, 0x04, 0x00000001 },
{ 0x001944, 1, 0x04, 0x00000000 },
{ 0x001514, 1, 0x04, 0x00000000 },
{ 0x000d68, 1, 0x04, 0x0000ffff },
{ 0x00121c, 1, 0x04, 0x0fac6881 },
{ 0x000fac, 1, 0x04, 0x00000001 },
{ 0x001538, 1, 0x04, 0x00000001 },
{ 0x000fe0, 2, 0x04, 0x00000000 },
{ 0x000fe8, 1, 0x04, 0x00000014 },
{ 0x000fec, 1, 0x04, 0x00000040 },
{ 0x000ff0, 1, 0x04, 0x00000000 },
{ 0x00179c, 1, 0x04, 0x00000000 },
{ 0x001228, 1, 0x04, 0x00000400 },
{ 0x00122c, 1, 0x04, 0x00000300 },
{ 0x001230, 1, 0x04, 0x00010001 },
{ 0x0007f8, 1, 0x04, 0x00000000 },
{ 0x0015b4, 1, 0x04, 0x00000001 },
{ 0x0015cc, 1, 0x04, 0x00000000 },
{ 0x001534, 1, 0x04, 0x00000000 },
{ 0x000fb0, 1, 0x04, 0x00000000 },
{ 0x0015d0, 1, 0x04, 0x00000000 },
{ 0x00153c, 1, 0x04, 0x00000000 },
{ 0x0016b4, 1, 0x04, 0x00000003 },
{ 0x000fbc, 4, 0x04, 0x0000ffff },
{ 0x000df8, 2, 0x04, 0x00000000 },
{ 0x001948, 1, 0x04, 0x00000000 },
{ 0x001970, 1, 0x04, 0x00000001 },
{ 0x00161c, 1, 0x04, 0x000009f0 },
{ 0x000dcc, 1, 0x04, 0x00000010 },
{ 0x00163c, 1, 0x04, 0x00000000 },
{ 0x0015e4, 1, 0x04, 0x00000000 },
{ 0x001160, 32, 0x04, 0x25e00040 },
{ 0x001880, 32, 0x04, 0x00000000 },
{ 0x000f84, 2, 0x04, 0x00000000 },
{ 0x0017c8, 2, 0x04, 0x00000000 },
{ 0x0017d0, 1, 0x04, 0x000000ff },
{ 0x0017d4, 1, 0x04, 0xffffffff },
{ 0x0017d8, 1, 0x04, 0x00000002 },
{ 0x0017dc, 1, 0x04, 0x00000000 },
{ 0x0015f4, 2, 0x04, 0x00000000 },
{ 0x001434, 2, 0x04, 0x00000000 },
{ 0x000d74, 1, 0x04, 0x00000000 },
{ 0x000dec, 1, 0x04, 0x00000001 },
{ 0x0013a4, 1, 0x04, 0x00000000 },
{ 0x001318, 1, 0x04, 0x00000001 },
{ 0x001644, 1, 0x04, 0x00000000 },
{ 0x000748, 1, 0x04, 0x00000000 },
{ 0x000de8, 1, 0x04, 0x00000000 },
{ 0x001648, 1, 0x04, 0x00000000 },
{ 0x0012a4, 1, 0x04, 0x00000000 },
{ 0x001120, 4, 0x04, 0x00000000 },
{ 0x001118, 1, 0x04, 0x00000000 },
{ 0x00164c, 1, 0x04, 0x00000000 },
{ 0x001658, 1, 0x04, 0x00000000 },
{ 0x001910, 1, 0x04, 0x00000290 },
{ 0x001518, 1, 0x04, 0x00000000 },
{ 0x00165c, 1, 0x04, 0x00000001 },
{ 0x001520, 1, 0x04, 0x00000000 },
{ 0x001604, 1, 0x04, 0x00000000 },
{ 0x001570, 1, 0x04, 0x00000000 },
{ 0x0013b0, 2, 0x04, 0x3f800000 },
{ 0x00020c, 1, 0x04, 0x00000000 },
{ 0x001670, 1, 0x04, 0x30201000 },
{ 0x001674, 1, 0x04, 0x70605040 },
{ 0x001678, 1, 0x04, 0xb8a89888 },
{ 0x00167c, 1, 0x04, 0xf8e8d8c8 },
{ 0x00166c, 1, 0x04, 0x00000000 },
{ 0x001680, 1, 0x04, 0x00ffff00 },
{ 0x0012d0, 1, 0x04, 0x00000003 },
{ 0x0012d4, 1, 0x04, 0x00000002 },
{ 0x001684, 2, 0x04, 0x00000000 },
{ 0x000dac, 2, 0x04, 0x00001b02 },
{ 0x000db4, 1, 0x04, 0x00000000 },
{ 0x00168c, 1, 0x04, 0x00000000 },
{ 0x0015bc, 1, 0x04, 0x00000000 },
{ 0x00156c, 1, 0x04, 0x00000000 },
{ 0x00187c, 1, 0x04, 0x00000000 },
{ 0x001110, 1, 0x04, 0x00000001 },
{ 0x000dc0, 3, 0x04, 0x00000000 },
{ 0x001234, 1, 0x04, 0x00000000 },
{ 0x001690, 1, 0x04, 0x00000000 },
{ 0x0012ac, 1, 0x04, 0x00000001 },
{ 0x0002c4, 1, 0x04, 0x00000000 },
{ 0x000790, 5, 0x04, 0x00000000 },
{ 0x00077c, 1, 0x04, 0x00000000 },
{ 0x001000, 1, 0x04, 0x00000010 },
{ 0x0010fc, 1, 0x04, 0x00000000 },
{ 0x001290, 1, 0x04, 0x00000000 },
{ 0x000218, 1, 0x04, 0x00000010 },
{ 0x0012d8, 1, 0x04, 0x00000000 },
{ 0x0012dc, 1, 0x04, 0x00000010 },
{ 0x000d94, 1, 0x04, 0x00000001 },
{ 0x00155c, 2, 0x04, 0x00000000 },
{ 0x001564, 1, 0x04, 0x00000fff },
{ 0x001574, 2, 0x04, 0x00000000 },
{ 0x00157c, 1, 0x04, 0x000fffff },
{ 0x001354, 1, 0x04, 0x00000000 },
{ 0x001610, 1, 0x04, 0x00000012 },
{ 0x001608, 2, 0x04, 0x00000000 },
{ 0x00260c, 1, 0x04, 0x00000000 },
{ 0x0007ac, 1, 0x04, 0x00000000 },
{ 0x00162c, 1, 0x04, 0x00000003 },
{ 0x000210, 1, 0x04, 0x00000000 },
{ 0x000320, 1, 0x04, 0x00000000 },
{ 0x000324, 6, 0x04, 0x3f800000 },
{ 0x000750, 1, 0x04, 0x00000000 },
{ 0x000760, 1, 0x04, 0x39291909 },
{ 0x000764, 1, 0x04, 0x79695949 },
{ 0x000768, 1, 0x04, 0xb9a99989 },
{ 0x00076c, 1, 0x04, 0xf9e9d9c9 },
{ 0x000770, 1, 0x04, 0x30201000 },
{ 0x000774, 1, 0x04, 0x70605040 },
{ 0x000778, 1, 0x04, 0x00009080 },
{ 0x000780, 1, 0x04, 0x39291909 },
{ 0x000784, 1, 0x04, 0x79695949 },
{ 0x000788, 1, 0x04, 0xb9a99989 },
{ 0x00078c, 1, 0x04, 0xf9e9d9c9 },
{ 0x0007d0, 1, 0x04, 0x30201000 },
{ 0x0007d4, 1, 0x04, 0x70605040 },
{ 0x0007d8, 1, 0x04, 0x00009080 },
{ 0x00037c, 1, 0x04, 0x00000001 },
{ 0x000740, 2, 0x04, 0x00000000 },
{ 0x002600, 1, 0x04, 0x00000000 },
{ 0x001918, 1, 0x04, 0x00000000 },
{ 0x00191c, 1, 0x04, 0x00000900 },
{ 0x001920, 1, 0x04, 0x00000405 },
{ 0x001308, 1, 0x04, 0x00000001 },
{ 0x001924, 1, 0x04, 0x00000000 },
{ 0x0013ac, 1, 0x04, 0x00000000 },
{ 0x00192c, 1, 0x04, 0x00000001 },
{ 0x00193c, 1, 0x04, 0x00002c1c },
{ 0x000d7c, 1, 0x04, 0x00000000 },
{ 0x000f8c, 1, 0x04, 0x00000000 },
{ 0x0002c0, 1, 0x04, 0x00000001 },
{ 0x001510, 1, 0x04, 0x00000000 },
{ 0x001940, 1, 0x04, 0x00000000 },
{ 0x000ff4, 2, 0x04, 0x00000000 },
{ 0x00194c, 2, 0x04, 0x00000000 },
{ 0x001968, 1, 0x04, 0x00000000 },
{ 0x001590, 1, 0x04, 0x0000003f },
{ 0x0007e8, 4, 0x04, 0x00000000 },
{ 0x00196c, 1, 0x04, 0x00000011 },
{ 0x0002e4, 1, 0x04, 0x0000b001 },
{ 0x00036c, 2, 0x04, 0x00000000 },
{ 0x00197c, 1, 0x04, 0x00000000 },
{ 0x000fcc, 2, 0x04, 0x00000000 },
{ 0x0002d8, 1, 0x04, 0x00000040 },
{ 0x001980, 1, 0x04, 0x00000080 },
{ 0x001504, 1, 0x04, 0x00000080 },
{ 0x001984, 1, 0x04, 0x00000000 },
{ 0x000300, 1, 0x04, 0x00000001 },
{ 0x0013a8, 1, 0x04, 0x00000000 },
{ 0x0012ec, 1, 0x04, 0x00000000 },
{ 0x001310, 1, 0x04, 0x00000000 },
{ 0x001314, 1, 0x04, 0x00000001 },
{ 0x001380, 1, 0x04, 0x00000000 },
{ 0x001384, 4, 0x04, 0x00000001 },
{ 0x001394, 1, 0x04, 0x00000000 },
{ 0x00139c, 1, 0x04, 0x00000000 },
{ 0x001398, 1, 0x04, 0x00000000 },
{ 0x001594, 1, 0x04, 0x00000000 },
{ 0x001598, 4, 0x04, 0x00000001 },
{ 0x000f54, 3, 0x04, 0x00000000 },
{ 0x0019bc, 1, 0x04, 0x00000000 },
{ 0x000f9c, 2, 0x04, 0x00000000 },
{ 0x0012cc, 1, 0x04, 0x00000000 },
{ 0x0012e8, 1, 0x04, 0x00000000 },
{ 0x00130c, 1, 0x04, 0x00000001 },
{ 0x001360, 8, 0x04, 0x00000000 },
{ 0x00133c, 2, 0x04, 0x00000001 },
{ 0x001344, 1, 0x04, 0x00000002 },
{ 0x001348, 2, 0x04, 0x00000001 },
{ 0x001350, 1, 0x04, 0x00000002 },
{ 0x001358, 1, 0x04, 0x00000001 },
{ 0x0012e4, 1, 0x04, 0x00000000 },
{ 0x00131c, 4, 0x04, 0x00000000 },
{ 0x0019c0, 1, 0x04, 0x00000000 },
{ 0x001140, 1, 0x04, 0x00000000 },
{ 0x0019c4, 1, 0x04, 0x00000000 },
{ 0x0019c8, 1, 0x04, 0x00001500 },
{ 0x00135c, 1, 0x04, 0x00000000 },
{ 0x000f90, 1, 0x04, 0x00000000 },
{ 0x0019e0, 8, 0x04, 0x00000001 },
{ 0x0019cc, 1, 0x04, 0x00000001 },
{ 0x0015b8, 1, 0x04, 0x00000000 },
{ 0x001a00, 1, 0x04, 0x00001111 },
{ 0x001a04, 7, 0x04, 0x00000000 },
{ 0x000d6c, 2, 0x04, 0xffff0000 },
{ 0x0010f8, 1, 0x04, 0x00001010 },
{ 0x000d80, 5, 0x04, 0x00000000 },
{ 0x000da0, 1, 0x04, 0x00000000 },
{ 0x0007a4, 2, 0x04, 0x00000000 },
{ 0x001508, 1, 0x04, 0x80000000 },
{ 0x00150c, 1, 0x04, 0x40000000 },
{ 0x001668, 1, 0x04, 0x00000000 },
{ 0x000318, 2, 0x04, 0x00000008 },
{ 0x000d9c, 1, 0x04, 0x00000001 },
{ 0x000ddc, 1, 0x04, 0x00000002 },
{ 0x000374, 1, 0x04, 0x00000000 },
{ 0x000378, 1, 0x04, 0x00000020 },
{ 0x0007dc, 1, 0x04, 0x00000000 },
{ 0x00074c, 1, 0x04, 0x00000055 },
{ 0x001420, 1, 0x04, 0x00000003 },
{ 0x0017bc, 2, 0x04, 0x00000000 },
{ 0x0017c4, 1, 0x04, 0x00000001 },
{ 0x001008, 1, 0x04, 0x00000008 },
{ 0x00100c, 1, 0x04, 0x00000040 },
{ 0x001010, 1, 0x04, 0x0000012c },
{ 0x000d60, 1, 0x04, 0x00000040 },
{ 0x00075c, 1, 0x04, 0x00000003 },
{ 0x001018, 1, 0x04, 0x00000020 },
{ 0x00101c, 1, 0x04, 0x00000001 },
{ 0x001020, 1, 0x04, 0x00000020 },
{ 0x001024, 1, 0x04, 0x00000001 },
{ 0x001444, 3, 0x04, 0x00000000 },
{ 0x000360, 1, 0x04, 0x20164010 },
{ 0x000364, 1, 0x04, 0x00000020 },
{ 0x000368, 1, 0x04, 0x00000000 },
{ 0x000de4, 1, 0x04, 0x00000000 },
{ 0x000204, 1, 0x04, 0x00000006 },
{ 0x000208, 1, 0x04, 0x00000000 },
{ 0x0002cc, 2, 0x04, 0x003fffff },
{ 0x001220, 1, 0x04, 0x00000005 },
{ 0x000fdc, 1, 0x04, 0x00000000 },
{ 0x000f98, 1, 0x04, 0x00400008 },
{ 0x001284, 1, 0x04, 0x08000080 },
{ 0x001450, 1, 0x04, 0x00400008 },
{ 0x001454, 1, 0x04, 0x08000080 },
{ 0x000214, 1, 0x04, 0x00000000 },
{}
};
const struct nvc0_graph_pack
nvf0_grctx_pack_mthd[] = {
{ nvf0_grctx_init_a197_0, 0xa197 },
{ nvc0_grctx_init_902d_0, 0x902d },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_fe_0[] = {
{ 0x404004, 8, 0x04, 0x00000000 },
{ 0x404024, 1, 0x04, 0x0000e000 },
{ 0x404028, 8, 0x04, 0x00000000 },
{ 0x4040a8, 8, 0x04, 0x00000000 },
{ 0x4040c8, 1, 0x04, 0xf800008f },
{ 0x4040d0, 6, 0x04, 0x00000000 },
{ 0x4040e8, 1, 0x04, 0x00001000 },
{ 0x4040f8, 1, 0x04, 0x00000000 },
{ 0x404100, 10, 0x04, 0x00000000 },
{ 0x404130, 2, 0x04, 0x00000000 },
{ 0x404138, 1, 0x04, 0x20000040 },
{ 0x404150, 1, 0x04, 0x0000002e },
{ 0x404154, 1, 0x04, 0x00000400 },
{ 0x404158, 1, 0x04, 0x00000200 },
{ 0x404164, 1, 0x04, 0x00000055 },
{ 0x40417c, 2, 0x04, 0x00000000 },
{ 0x4041a0, 4, 0x04, 0x00000000 },
{ 0x404200, 1, 0x04, 0x0000a197 },
{ 0x404204, 1, 0x04, 0x0000a1c0 },
{ 0x404208, 1, 0x04, 0x0000a140 },
{ 0x40420c, 1, 0x04, 0x0000902d },
{}
};
const struct nvc0_graph_init
nvf0_grctx_init_pri_0[] = {
{ 0x404404, 12, 0x04, 0x00000000 },
{ 0x404438, 1, 0x04, 0x00000000 },
{ 0x404460, 2, 0x04, 0x00000000 },
{ 0x404468, 1, 0x04, 0x00ffffff },
{ 0x40446c, 1, 0x04, 0x00000000 },
{ 0x404480, 1, 0x04, 0x00000001 },
{ 0x404498, 1, 0x04, 0x00000001 },
{}
};
const struct nvc0_graph_init
nvf0_grctx_init_cwd_0[] = {
{ 0x405b00, 1, 0x04, 0x00000000 },
{ 0x405b10, 1, 0x04, 0x00001000 },
{ 0x405b20, 1, 0x04, 0x04000000 },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_pd_0[] = {
{ 0x406020, 1, 0x04, 0x034103c1 },
{ 0x406028, 4, 0x04, 0x00000001 },
{ 0x4064a8, 1, 0x04, 0x00000000 },
{ 0x4064ac, 1, 0x04, 0x00003fff },
{ 0x4064b0, 3, 0x04, 0x00000000 },
{ 0x4064c0, 1, 0x04, 0x802000f0 },
{ 0x4064c4, 1, 0x04, 0x0192ffff },
{ 0x4064c8, 1, 0x04, 0x018007c0 },
{ 0x4064cc, 9, 0x04, 0x00000000 },
{ 0x4064fc, 1, 0x04, 0x0000022a },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_be_0[] = {
{ 0x408800, 1, 0x04, 0x12802a3c },
{ 0x408804, 1, 0x04, 0x00000040 },
{ 0x408808, 1, 0x04, 0x1003e005 },
{ 0x408840, 1, 0x04, 0x0000000b },
{ 0x408900, 1, 0x04, 0x3080b801 },
{ 0x408904, 1, 0x04, 0x62000001 },
{ 0x408908, 1, 0x04, 0x00c8102f },
{ 0x408980, 1, 0x04, 0x0000011d },
{}
};
static const struct nvc0_graph_pack
nvf0_grctx_pack_hub[] = {
{ nvc0_grctx_init_main_0 },
{ nvf0_grctx_init_fe_0 },
{ nvf0_grctx_init_pri_0 },
{ nve4_grctx_init_memfmt_0 },
{ nve4_grctx_init_ds_0 },
{ nvf0_grctx_init_cwd_0 },
{ nvf0_grctx_init_pd_0 },
{ nvc0_grctx_init_rstr2d_0 },
{ nve4_grctx_init_scc_0 },
{ nvf0_grctx_init_be_0 },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_setup_0[] = {
{ 0x418800, 1, 0x04, 0x7006860a },
{ 0x418808, 1, 0x04, 0x00000000 },
{ 0x41880c, 1, 0x04, 0x00000030 },
{ 0x418810, 1, 0x04, 0x00000000 },
{ 0x418828, 1, 0x04, 0x00000044 },
{ 0x418830, 1, 0x04, 0x10000001 },
{ 0x4188d8, 1, 0x04, 0x00000008 },
{ 0x4188e0, 1, 0x04, 0x01000000 },
{ 0x4188e8, 5, 0x04, 0x00000000 },
{ 0x4188fc, 1, 0x04, 0x20100018 },
{}
};
const struct nvc0_graph_init
nvf0_grctx_init_gpc_unk_2[] = {
{ 0x418d24, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
nvf0_grctx_pack_gpc[] = {
{ nvc0_grctx_init_gpc_unk_0 },
{ nvd9_grctx_init_prop_0 },
{ nvd9_grctx_init_gpc_unk_1 },
{ nvf0_grctx_init_setup_0 },
{ nvc0_grctx_init_zcull_0 },
{ nvd9_grctx_init_crstr_0 },
{ nve4_grctx_init_gpm_0 },
{ nvf0_grctx_init_gpc_unk_2 },
{ nvc0_grctx_init_gcc_0 },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_tex_0[] = {
{ 0x419a00, 1, 0x04, 0x000000f0 },
{ 0x419a04, 1, 0x04, 0x00000001 },
{ 0x419a08, 1, 0x04, 0x00000021 },
{ 0x419a0c, 1, 0x04, 0x00020000 },
{ 0x419a10, 1, 0x04, 0x00000000 },
{ 0x419a14, 1, 0x04, 0x00000200 },
{ 0x419a1c, 1, 0x04, 0x0000c000 },
{ 0x419a20, 1, 0x04, 0x00020800 },
{ 0x419a30, 1, 0x04, 0x00000001 },
{ 0x419ac4, 1, 0x04, 0x0037f440 },
{}
};
const struct nvc0_graph_init
nvf0_grctx_init_mpc_0[] = {
{ 0x419c00, 1, 0x04, 0x0000001a },
{ 0x419c04, 1, 0x04, 0x80000006 },
{ 0x419c08, 1, 0x04, 0x00000002 },
{ 0x419c20, 1, 0x04, 0x00000000 },
{ 0x419c24, 1, 0x04, 0x00084210 },
{ 0x419c28, 1, 0x04, 0x3efbefbe },
{}
};
const struct nvc0_graph_init
nvf0_grctx_init_l1c_0[] = {
{ 0x419ce8, 1, 0x04, 0x00000000 },
{ 0x419cf4, 1, 0x04, 0x00000203 },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_sm_0[] = {
{ 0x419e04, 1, 0x04, 0x00000000 },
{ 0x419e08, 1, 0x04, 0x0000001d },
{ 0x419e0c, 1, 0x04, 0x00000000 },
{ 0x419e10, 1, 0x04, 0x00001c02 },
{ 0x419e44, 1, 0x04, 0x0013eff2 },
{ 0x419e48, 1, 0x04, 0x00000000 },
{ 0x419e4c, 1, 0x04, 0x0000007f },
{ 0x419e50, 2, 0x04, 0x00000000 },
{ 0x419e58, 1, 0x04, 0x00000001 },
{ 0x419e5c, 3, 0x04, 0x00000000 },
{ 0x419e68, 1, 0x04, 0x00000002 },
{ 0x419e6c, 12, 0x04, 0x00000000 },
{ 0x419eac, 1, 0x04, 0x00001f8f },
{ 0x419eb0, 1, 0x04, 0x0db00d2f },
{ 0x419eb8, 1, 0x04, 0x00000000 },
{ 0x419ec8, 1, 0x04, 0x0001304f },
{ 0x419f30, 4, 0x04, 0x00000000 },
{ 0x419f40, 1, 0x04, 0x00000018 },
{ 0x419f44, 3, 0x04, 0x00000000 },
{ 0x419f58, 1, 0x04, 0x00000000 },
{ 0x419f70, 1, 0x04, 0x00007300 },
{ 0x419f78, 1, 0x04, 0x000000eb },
{ 0x419f7c, 1, 0x04, 0x00000404 },
{}
};
static const struct nvc0_graph_pack
nvf0_grctx_pack_tpc[] = {
{ nvd7_grctx_init_pe_0 },
{ nvf0_grctx_init_tex_0 },
{ nvf0_grctx_init_mpc_0 },
{ nvf0_grctx_init_l1c_0 },
{ nvf0_grctx_init_sm_0 },
{}
};
static const struct nvc0_graph_init
nvf0_grctx_init_cbm_0[] = {
{ 0x41bec0, 1, 0x04, 0x10000000 },
{ 0x41bec4, 1, 0x04, 0x00037f7f },
{ 0x41bee4, 1, 0x04, 0x00000000 },
{}
};
static const struct nvc0_graph_pack
nvf0_grctx_pack_ppc[] = {
{ nve4_grctx_init_pes_0 },
{ nvf0_grctx_init_cbm_0 },
{ nvd7_grctx_init_wwdx_0 },
{}
};
/*******************************************************************************
* PGRAPH context implementation
******************************************************************************/
static void
nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
{
u32 magic[GPC_MAX][4];
u32 offset;
int gpc;
mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
mmio_list(0x40800c, 0x00000000, 8, 1);
mmio_list(0x408010, 0x80000000, 0, 0);
mmio_list(0x419004, 0x00000000, 8, 1);
mmio_list(0x419008, 0x00000000, 0, 0);
mmio_list(0x4064cc, 0x80000000, 0, 0);
mmio_list(0x408004, 0x00000000, 8, 0);
mmio_list(0x408008, 0x80000030, 0, 0);
mmio_list(0x418808, 0x00000000, 8, 0);
mmio_list(0x41880c, 0x80000030, 0, 0);
mmio_list(0x4064c8, 0x01800600, 0, 0);
mmio_list(0x418810, 0x80000000, 12, 2);
mmio_list(0x419848, 0x10000000, 12, 2);
mmio_list(0x405830, 0x02180648, 0, 0);
mmio_list(0x4064c4, 0x0192ffff, 0, 0);
for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) {
u16 magic0 = 0x0218 * (priv->tpc_nr[gpc] - 1);
u16 magic1 = 0x0648 * (priv->tpc_nr[gpc] - 1);
u16 magic2 = 0x0218;
u16 magic3 = 0x0648;
magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset;
magic[gpc][1] = 0x00000000 | (magic1 << 16);
offset += 0x0324 * (priv->tpc_nr[gpc] - 1);;
magic[gpc][2] = 0x10000000 | (magic2 << 16) | offset;
magic[gpc][3] = 0x00000000 | (magic3 << 16);
offset += 0x0324;
}
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0);
mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0);
offset += 0x07ff * (priv->tpc_nr[gpc] - 1);
mmio_list(GPC_UNIT(gpc, 0x32c0), magic[gpc][2], 0, 0);
mmio_list(GPC_UNIT(gpc, 0x32e4), magic[gpc][3] | offset, 0, 0);
offset += 0x07ff;
}
mmio_list(0x17e91c, 0x06060609, 0, 0);
mmio_list(0x17e920, 0x00090a05, 0, 0);
}
struct nouveau_oclass *
nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) {
.base.handle = NV_ENGCTX(GR, 0xf0),
.base.ofuncs = &(struct nouveau_ofuncs) {
.ctor = nvc0_graph_context_ctor,
.dtor = nvc0_graph_context_dtor,
.init = _nouveau_graph_context_init,
.fini = _nouveau_graph_context_fini,
.rd32 = _nouveau_graph_context_rd32,
.wr32 = _nouveau_graph_context_wr32,
},
.main = nve4_grctx_generate_main,
.mods = nvf0_grctx_generate_mods,
.unkn = nve4_grctx_generate_unkn,
.hub = nvf0_grctx_pack_hub,
.gpc = nvf0_grctx_pack_gpc,
.zcull = nvc0_grctx_pack_zcull,
.tpc = nvf0_grctx_pack_tpc,
.ppc = nvf0_grctx_pack_ppc,
.icmd = nvf0_grctx_pack_icmd,
.mthd = nvf0_grctx_pack_mthd,
}.base;

View File

@ -0,0 +1,335 @@
/* fuc microcode util functions for nvc0 PGRAPH
*
* 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_CODE
// queue_put - add request to queue
//
// In : $r13 queue pointer
// $r14 command
// $r15 data
//
queue_put:
// make sure we have space..
ld b32 $r8 D[$r13 + 0x0] // GET
ld b32 $r9 D[$r13 + 0x4] // PUT
xor $r8 8
cmpu b32 $r8 $r9
bra ne #queue_put_next
mov $r15 E_CMD_OVERFLOW
call(error)
ret
// store cmd/data on queue
queue_put_next:
and $r8 $r9 7
shl b32 $r8 3
add b32 $r8 $r13
add b32 $r8 8
st b32 D[$r8 + 0x0] $r14
st b32 D[$r8 + 0x4] $r15
// update PUT
add b32 $r9 1
and $r9 0xf
st b32 D[$r13 + 0x4] $r9
ret
// queue_get - fetch request from queue
//
// In : $r13 queue pointer
//
// Out: $p1 clear on success (data available)
// $r14 command
// $r15 data
//
queue_get:
bset $flags $p1
ld b32 $r8 D[$r13 + 0x0] // GET
ld b32 $r9 D[$r13 + 0x4] // PUT
cmpu b32 $r8 $r9
bra e #queue_get_done
// fetch first cmd/data pair
and $r9 $r8 7
shl b32 $r9 3
add b32 $r9 $r13
add b32 $r9 8
ld b32 $r14 D[$r9 + 0x0]
ld b32 $r15 D[$r9 + 0x4]
// update GET
add b32 $r8 1
and $r8 0xf
st b32 D[$r13 + 0x0] $r8
bclr $flags $p1
queue_get_done:
ret
// nv_rd32 - read 32-bit value from nv register
//
// In : $r14 register
// Out: $r15 value
//
nv_rd32:
mov b32 $r12 $r14
bset $r12 31 // MMIO_CTRL_PENDING
nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)
nv_rd32_wait:
nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)
xbit $r12 $r12 31
bra ne #nv_rd32_wait
mov $r10 6 // DONE_MMIO_RD
call(wait_doneo)
nv_iord($r15, NV_PGRAPH_FECS_MMIO_RDVAL, 0)
ret
// nv_wr32 - write 32-bit value to nv register
//
// In : $r14 register
// $r15 value
//
nv_wr32:
nv_iowr(NV_PGRAPH_FECS_MMIO_WRVAL, 0, $r15)
mov b32 $r12 $r14
bset $r12 31 // MMIO_CTRL_PENDING
bset $r12 30 // MMIO_CTRL_WRITE
nv_iowr(NV_PGRAPH_FECS_MMIO_CTRL, 0, $r12)
nv_wr32_wait:
nv_iord($r12, NV_PGRAPH_FECS_MMIO_CTRL, 0)
xbit $r12 $r12 31
bra ne #nv_wr32_wait
ret
// wait_donez - wait on FUC_DONE bit to become clear
//
// In : $r10 bit to wait on
//
wait_donez:
trace_set(T_WAIT);
nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
wait_donez_ne:
nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
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
//
wait_doneo:
trace_set(T_WAIT);
nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(6), 0, $r10)
wait_doneo_e:
nv_iord($r8, NV_PGRAPH_FECS_SIGNAL, 0)
xbit $r8 $r8 $r10
bra e #wait_doneo_e
trace_clr(T_WAIT)
ret
// mmctx_size - determine size of a mmio list transfer
//
// In : $r14 mmio list head
// $r15 mmio list tail
// Out: $r15 transfer size (in bytes)
//
mmctx_size:
clear b32 $r9
nv_mmctx_size_loop:
ld b32 $r8 D[$r14]
shr b32 $r8 26
add b32 $r8 1
shl b32 $r8 2
add b32 $r9 $r8
add b32 $r14 4
cmpu b32 $r14 $r15
bra ne #nv_mmctx_size_loop
mov b32 $r15 $r9
ret
// mmctx_xfer - execute a list of mmio transfers
//
// In : $r10 flags
// bit 0: direction (0 = save, 1 = load)
// bit 1: set if first transfer
// bit 2: set if last transfer
// $r11 base
// $r12 mmio list head
// $r13 mmio list tail
// $r14 multi_stride
// $r15 multi_mask
//
mmctx_xfer:
trace_set(T_MMCTX)
clear b32 $r9
or $r11 $r11
bra e #mmctx_base_disabled
nv_iowr(NV_PGRAPH_FECS_MMCTX_BASE, 0, $r11)
bset $r9 0 // BASE_EN
mmctx_base_disabled:
or $r14 $r14
bra e #mmctx_multi_disabled
nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_STRIDE, 0, $r14)
nv_iowr(NV_PGRAPH_FECS_MMCTX_MULTI_MASK, 0, $r15)
bset $r9 1 // MULTI_EN
mmctx_multi_disabled:
xbit $r11 $r10 0
shl b32 $r11 16 // DIR
bset $r11 12 // QLIMIT = 0x10
xbit $r14 $r10 1
shl b32 $r14 17
or $r11 $r14 // START_TRIGGER
nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)
// loop over the mmio list, and send requests to the hw
mmctx_exec_loop:
// wait for space in mmctx queue
mmctx_wait_free:
nv_iord($r14, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
and $r14 0x1f
bra e #mmctx_wait_free
// queue up an entry
ld b32 $r14 D[$r12]
or $r14 $r9
nv_iowr(NV_PGRAPH_FECS_MMCTX_QUEUE, 0, $r14)
add b32 $r12 4
cmpu b32 $r12 $r13
bra ne #mmctx_exec_loop
xbit $r11 $r10 2
bra ne #mmctx_stop
// wait for queue to empty
mmctx_fini_wait:
nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
and $r11 0x1f
cmpu b32 $r11 0x10
bra ne #mmctx_fini_wait
mov $r10 5 // DONE_MMCTX
call(wait_donez)
bra #mmctx_done
mmctx_stop:
xbit $r11 $r10 0
shl b32 $r11 16 // DIR
bset $r11 12 // QLIMIT = 0x10
bset $r11 18 // STOP_TRIGGER
nv_iowr(NV_PGRAPH_FECS_MMCTX_CTRL, 0, $r11)
mmctx_stop_wait:
// wait for STOP_TRIGGER to clear
nv_iord($r11, NV_PGRAPH_FECS_MMCTX_CTRL, 0)
xbit $r11 $r11 18
bra ne #mmctx_stop_wait
mmctx_done:
trace_clr(T_MMCTX)
ret
// Wait for DONE_STRAND
//
strand_wait:
push $r10
mov $r10 2
call(wait_donez)
pop $r10
ret
// unknown - call before issuing strand commands
//
strand_pre:
mov $r9 NV_PGRAPH_FECS_STRAND_CMD_ENABLE
nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)
call(strand_wait)
ret
// unknown - call after issuing strand commands
//
strand_post:
mov $r9 NV_PGRAPH_FECS_STRAND_CMD_DISABLE
nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r9)
call(strand_wait)
ret
// Selects strand set?!
//
// In: $r14 id
//
strand_set:
mov $r12 0xf
nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r12)
mov $r12 NV_PGRAPH_FECS_STRAND_CMD_DEACTIVATE_FILTER
nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
nv_iowr(NV_PGRAPH_FECS_STRAND_FILTER, 0x3f, $r14)
mov $r12 NV_PGRAPH_FECS_STRAND_CMD_ACTIVATE_FILTER
nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
call(strand_wait)
ret
// Initialise strand context data
//
// In : $r15 context base
// Out: $r15 context size (in bytes)
//
// Strandset(?) 3 hardcoded currently
//
strand_ctx_init:
trace_set(T_STRINIT)
call(strand_pre)
mov $r14 3
call(strand_set)
clear b32 $r12
nv_iowr(NV_PGRAPH_FECS_STRAND_SELECT, 0x3f, $r12)
mov $r12 NV_PGRAPH_FECS_STRAND_CMD_SEEK
nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
call(strand_wait)
sub b32 $r12 $r0 1
nv_iowr(NV_PGRAPH_FECS_STRAND_DATA, 0x3f, $r12)
mov $r12 NV_PGRAPH_FECS_STRAND_CMD_GET_INFO
nv_iowr(NV_PGRAPH_FECS_STRAND_CMD, 0x3f, $r12)
call(strand_wait)
call(strand_post)
// read the size of each strand, poke the context offset of
// each into STRAND_{SAVE,LOAD}_SWBASE now, no need to worry
// about it later then.
nv_mkio($r8, NV_PGRAPH_FECS_STRAND_SAVE_SWBASE, 0x00)
nv_iord($r9, NV_PGRAPH_FECS_STRANDS_CNT, 0x00)
shr b32 $r14 $r15 8
ctx_init_strand_loop:
iowr I[$r8 + 0x000] $r14 // STRAND_SAVE_SWBASE
iowr I[$r8 + 0x100] $r14 // STRAND_LOAD_SWBASE
iord $r10 I[$r8 + 0x200] // STRAND_SIZE
shr b32 $r10 6
add b32 $r10 1
add b32 $r14 $r10
add b32 $r8 4
sub b32 $r9 1
bra ne #ctx_init_strand_loop
shl b32 $r14 8
sub b32 $r15 $r14 $r15
trace_clr(T_STRINIT)
ret
#endif

Some files were not shown because too many files have changed in this diff Show More