Commit 91384758 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'linux-3.17' of git://anongit.freedesktop.org/git/nouveau/linux-2.6

Pull nouveau drm updates from Ben Skeggs:
 "Apologies for not getting this done in time for Dave's drm-next merge
  window.  As he mentioned, a pre-existing bug reared its head a lot
  more obviously after this lot of changes.  It took quite a bit of time
  to track it down.  In any case, Dave suggested I try my luck by
  sending directly to you this time.

  Overview:

   - more code for Tegra GK20A from NVIDIA - probing, reclockig
   - better fix for Kepler GPUs that have the graphics engine powered
     off on startup, method courtesy of info provided by NVIDIA
   - unhardcoding of a bunch of graphics engine setup on
     Fermi/Kepler/Maxwell, will hopefully solve some issues people have
     noticed on higher-end models
   - support for "Zero Bandwidth Clear" on Fermi/Kepler/Maxwell, needs
     userspace support in general, but some lucky apps will benefit
     automagically
   - reviewed/exposed the full object APIs to userspace (finally), gives
     it access to perfctrs, ZBC controls, various events.  More to come
     in the future.
   - various other fixes"
Acked-by: default avatarDave Airlie <airlied@redhat.com>

* 'linux-3.17' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (87 commits)
  drm/nouveau: expose the full object/event interfaces to userspace
  drm/nouveau: fix headless mode
  drm/nouveau: hide sysfs pstate file behind an option again
  drm/nv50/disp: shhh compiler
  drm/gf100-/gr: implement the proper SetShaderExceptions method
  drm/gf100-/gr: remove some broken ltc bashing, for now
  drm/gf100-/gr: unhardcode attribute cb config
  drm/gf100-/gr: fetch tpcs-per-ppc info on startup
  drm/gf100-/gr: unhardcode pagepool config
  drm/gf100-/gr: unhardcode bundle cb config
  drm/gf100-/gr: improve initial context patch list helpers
  drm/gf100-/gr: add support for zero bandwidth clear
  drm/nouveau/ltc: add zbc drivers
  drm/nouveau/ltc: s/ltcg/ltc/ + cleanup
  drm/nouveau: use ram info from nvif_device
  drm/nouveau/disp: implement nvif event sources for vblank/connector notifiers
  drm/nouveau/disp: allow user direct access to channel control registers
  drm/nouveau/disp: audit and version display classes
  drm/nouveau/disp: audit and version SCANOUTPOS method
  drm/nv50-/disp: audit and version PIOR_PWR method
  ...
parents c23190c0 27111a23
config DRM_NOUVEAU
tristate "Nouveau (nVidia) cards"
tristate "Nouveau (NVIDIA) cards"
depends on DRM && PCI
select FW_LOADER
select DRM_KMS_HELPER
......@@ -23,7 +23,15 @@ config DRM_NOUVEAU
select THERMAL if ACPI && X86
select ACPI_VIDEO if ACPI && X86
help
Choose this option for open-source nVidia support.
Choose this option for open-source NVIDIA support.
config NOUVEAU_PLATFORM_DRIVER
tristate "Nouveau (NVIDIA) SoC GPUs"
depends on DRM_NOUVEAU && ARCH_TEGRA
default y
help
Support for Nouveau platform driver, used for SoC GPUs as found
on NVIDIA Tegra K1.
config NOUVEAU_DEBUG
int "Maximum debug level"
......
......@@ -14,8 +14,10 @@ nouveau-y += core/core/enum.o
nouveau-y += core/core/event.o
nouveau-y += core/core/gpuobj.o
nouveau-y += core/core/handle.o
nouveau-y += core/core/ioctl.o
nouveau-y += core/core/mm.o
nouveau-y += core/core/namedb.o
nouveau-y += core/core/notify.o
nouveau-y += core/core/object.o
nouveau-y += core/core/option.o
nouveau-y += core/core/parent.o
......@@ -26,6 +28,7 @@ nouveau-y += core/core/subdev.o
nouveau-y += core/subdev/bar/base.o
nouveau-y += core/subdev/bar/nv50.o
nouveau-y += core/subdev/bar/nvc0.o
nouveau-y += core/subdev/bar/gk20a.o
nouveau-y += core/subdev/bios/base.o
nouveau-y += core/subdev/bios/bit.o
nouveau-y += core/subdev/bios/boost.o
......@@ -64,6 +67,7 @@ nouveau-y += core/subdev/clock/nva3.o
nouveau-y += core/subdev/clock/nvaa.o
nouveau-y += core/subdev/clock/nvc0.o
nouveau-y += core/subdev/clock/nve0.o
nouveau-y += core/subdev/clock/gk20a.o
nouveau-y += core/subdev/clock/pllnv04.o
nouveau-y += core/subdev/clock/pllnva3.o
nouveau-y += core/subdev/devinit/base.o
......@@ -149,8 +153,10 @@ nouveau-y += core/subdev/instmem/base.o
nouveau-y += core/subdev/instmem/nv04.o
nouveau-y += core/subdev/instmem/nv40.o
nouveau-y += core/subdev/instmem/nv50.o
nouveau-y += core/subdev/ltcg/gf100.o
nouveau-y += core/subdev/ltcg/gm107.o
nouveau-y += core/subdev/ltc/base.o
nouveau-y += core/subdev/ltc/gf100.o
nouveau-y += core/subdev/ltc/gk104.o
nouveau-y += core/subdev/ltc/gm107.o
nouveau-y += core/subdev/mc/base.o
nouveau-y += core/subdev/mc/nv04.o
nouveau-y += core/subdev/mc/nv40.o
......@@ -161,6 +167,7 @@ nouveau-y += core/subdev/mc/nv94.o
nouveau-y += core/subdev/mc/nv98.o
nouveau-y += core/subdev/mc/nvc0.o
nouveau-y += core/subdev/mc/nvc3.o
nouveau-y += core/subdev/mc/gk20a.o
nouveau-y += core/subdev/mxm/base.o
nouveau-y += core/subdev/mxm/mxms.o
nouveau-y += core/subdev/mxm/nv50.o
......@@ -169,6 +176,7 @@ nouveau-y += core/subdev/pwr/memx.o
nouveau-y += core/subdev/pwr/nva3.o
nouveau-y += core/subdev/pwr/nvc0.o
nouveau-y += core/subdev/pwr/nvd0.o
nouveau-y += core/subdev/pwr/gk104.o
nouveau-y += core/subdev/pwr/nv108.o
nouveau-y += core/subdev/therm/base.o
nouveau-y += core/subdev/therm/fan.o
......@@ -211,6 +219,7 @@ nouveau-y += core/engine/copy/nvc0.o
nouveau-y += core/engine/copy/nve0.o
nouveau-y += core/engine/crypt/nv84.o
nouveau-y += core/engine/crypt/nv98.o
nouveau-y += core/engine/device/acpi.o
nouveau-y += core/engine/device/base.o
nouveau-y += core/engine/device/ctrl.o
nouveau-y += core/engine/device/nv04.o
......@@ -270,6 +279,7 @@ nouveau-y += core/engine/graph/ctxnvd9.o
nouveau-y += core/engine/graph/ctxnve4.o
nouveau-y += core/engine/graph/ctxgk20a.o
nouveau-y += core/engine/graph/ctxnvf0.o
nouveau-y += core/engine/graph/ctxgk110b.o
nouveau-y += core/engine/graph/ctxnv108.o
nouveau-y += core/engine/graph/ctxgm107.o
nouveau-y += core/engine/graph/nv04.o
......@@ -291,6 +301,7 @@ nouveau-y += core/engine/graph/nvd9.o
nouveau-y += core/engine/graph/nve4.o
nouveau-y += core/engine/graph/gk20a.o
nouveau-y += core/engine/graph/nvf0.o
nouveau-y += core/engine/graph/gk110b.o
nouveau-y += core/engine/graph/nv108.o
nouveau-y += core/engine/graph/gm107.o
nouveau-y += core/engine/mpeg/nv31.o
......@@ -318,11 +329,18 @@ nouveau-y += core/engine/vp/nv98.o
nouveau-y += core/engine/vp/nvc0.o
nouveau-y += core/engine/vp/nve0.o
# nvif
nouveau-y += nvif/object.o
nouveau-y += nvif/client.o
nouveau-y += nvif/device.o
nouveau-y += nvif/notify.o
# drm/core
nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
nouveau-y += nouveau_vga.o nouveau_agp.o
nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
nouveau-y += nouveau_prime.o nouveau_abi16.o
nouveau-y += nouveau_nvif.o nouveau_usif.o
nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o
nouveau-y += nv50_fence.o nv84_fence.o nvc0_fence.o
......@@ -349,3 +367,6 @@ nouveau-$(CONFIG_DRM_NOUVEAU_BACKLIGHT) += nouveau_backlight.o
nouveau-$(CONFIG_DEBUG_FS) += nouveau_debugfs.o
obj-$(CONFIG_DRM_NOUVEAU)+= nouveau.o
# platform driver
obj-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
......@@ -26,13 +26,167 @@
#include <core/client.h>
#include <core/handle.h>
#include <core/option.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <nvif/unpack.h>
#include <nvif/event.h>
#include <engine/device.h>
struct nvkm_client_notify {
struct nouveau_client *client;
struct nvkm_notify n;
u8 version;
u8 size;
union {
struct nvif_notify_rep_v0 v0;
} rep;
};
static int
nvkm_client_notify(struct nvkm_notify *n)
{
struct nvkm_client_notify *notify = container_of(n, typeof(*notify), n);
struct nouveau_client *client = notify->client;
return client->ntfy(&notify->rep, notify->size, n->data, n->size);
}
int
nvkm_client_notify_put(struct nouveau_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (client->notify[index]) {
nvkm_notify_put(&client->notify[index]->n);
return 0;
}
}
return -ENOENT;
}
int
nvkm_client_notify_get(struct nouveau_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (client->notify[index]) {
nvkm_notify_get(&client->notify[index]->n);
return 0;
}
}
return -ENOENT;
}
int
nvkm_client_notify_del(struct nouveau_client *client, int index)
{
if (index < ARRAY_SIZE(client->notify)) {
if (client->notify[index]) {
nvkm_notify_fini(&client->notify[index]->n);
kfree(client->notify[index]);
client->notify[index] = NULL;
return 0;
}
}
return -ENOENT;
}
int
nvkm_client_notify_new(struct nouveau_client *client,
struct nvkm_event *event, void *data, u32 size)
{
struct nvkm_client_notify *notify;
union {
struct nvif_notify_req_v0 v0;
} *req = data;
u8 index, reply;
int ret;
for (index = 0; index < ARRAY_SIZE(client->notify); index++) {
if (!client->notify[index])
break;
}
if (index == ARRAY_SIZE(client->notify))
return -ENOSPC;
notify = kzalloc(sizeof(*notify), GFP_KERNEL);
if (!notify)
return -ENOMEM;
nv_ioctl(client, "notify new size %d\n", size);
if (nvif_unpack(req->v0, 0, 0, true)) {
nv_ioctl(client, "notify new vers %d reply %d route %02x "
"token %llx\n", req->v0.version,
req->v0.reply, req->v0.route, req->v0.token);
notify->version = req->v0.version;
notify->size = sizeof(notify->rep.v0);
notify->rep.v0.version = req->v0.version;
notify->rep.v0.route = req->v0.route;
notify->rep.v0.token = req->v0.token;
reply = req->v0.reply;
}
if (ret == 0) {
ret = nvkm_notify_init(event, nvkm_client_notify, false,
data, size, reply, &notify->n);
if (ret == 0) {
client->notify[index] = notify;
notify->client = client;
return 0;
}
}
kfree(notify);
return 0;
}
static int
nouveau_client_devlist(struct nouveau_object *object, void *data, u32 size)
{
union {
struct nv_client_devlist_v0 v0;
} *args = data;
int ret;
nv_ioctl(object, "client devlist size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
nv_ioctl(object, "client devlist vers %d count %d\n",
args->v0.version, args->v0.count);
if (size == sizeof(args->v0.device[0]) * args->v0.count) {
ret = nouveau_device_list(args->v0.device,
args->v0.count);
if (ret >= 0) {
args->v0.count = ret;
ret = 0;
}
} else {
ret = -EINVAL;
}
}
return ret;
}
static int
nouveau_client_mthd(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
{
switch (mthd) {
case NV_CLIENT_DEVLIST:
return nouveau_client_devlist(object, data, size);
default:
break;
}
return -EINVAL;
}
static void
nouveau_client_dtor(struct nouveau_object *object)
{
struct nouveau_client *client = (void *)object;
int i;
for (i = 0; i < ARRAY_SIZE(client->notify); i++)
nvkm_client_notify_del(client, i);
nouveau_object_ref(NULL, &client->device);
nouveau_handle_destroy(client->root);
nouveau_namedb_destroy(&client->base);
......@@ -42,6 +196,7 @@ static struct nouveau_oclass
nouveau_client_oclass = {
.ofuncs = &(struct nouveau_ofuncs) {
.dtor = nouveau_client_dtor,
.mthd = nouveau_client_mthd,
},
};
......@@ -93,9 +248,12 @@ int
nouveau_client_fini(struct nouveau_client *client, bool suspend)
{
const char *name[2] = { "fini", "suspend" };
int ret;
int ret, i;
nv_debug(client, "%s running\n", name[suspend]);
nv_debug(client, "%s notify\n", name[suspend]);
for (i = 0; i < ARRAY_SIZE(client->notify); i++)
nvkm_client_notify_put(client, i);
nv_debug(client, "%s object\n", name[suspend]);
ret = nouveau_handle_fini(client->root, suspend);
nv_debug(client, "%s completed with %d\n", name[suspend], ret);
return ret;
......
/*
* Copyright 2013 Red Hat Inc.
* Copyright 2013-2014 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"),
......@@ -24,173 +24,77 @@
#include <core/event.h>
void
nouveau_event_put(struct nouveau_eventh *handler)
nvkm_event_put(struct nvkm_event *event, u32 types, int index)
{
struct nouveau_event *event = handler->event;
unsigned long flags;
u32 m, t;
if (!__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags))
return;
spin_lock_irqsave(&event->refs_lock, flags);
for (m = handler->types; t = __ffs(m), m; m &= ~(1 << t)) {
if (!--event->refs[handler->index * event->types_nr + t]) {
if (event->disable)
event->disable(event, 1 << t, handler->index);
BUG_ON(!spin_is_locked(&event->refs_lock));
while (types) {
int type = __ffs(types); types &= ~(1 << type);
if (--event->refs[index * event->types_nr + type] == 0) {
if (event->func->fini)
event->func->fini(event, 1 << type, index);
}
}
spin_unlock_irqrestore(&event->refs_lock, flags);
}
void
nouveau_event_get(struct nouveau_eventh *handler)
nvkm_event_get(struct nvkm_event *event, u32 types, int index)
{
struct nouveau_event *event = handler->event;
unsigned long flags;
u32 m, t;
if (__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags))
return;
spin_lock_irqsave(&event->refs_lock, flags);
for (m = handler->types; t = __ffs(m), m; m &= ~(1 << t)) {
if (!event->refs[handler->index * event->types_nr + t]++) {
if (event->enable)
event->enable(event, 1 << t, handler->index);
BUG_ON(!spin_is_locked(&event->refs_lock));
while (types) {
int type = __ffs(types); types &= ~(1 << type);
if (++event->refs[index * event->types_nr + type] == 1) {
if (event->func->init)
event->func->init(event, 1 << type, 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, u32 types, int index,
int (*func)(void *, u32, int), void *priv,
struct nouveau_eventh *handler)
{
unsigned long flags;
if (types & ~((1 << event->types_nr) - 1))
return -EINVAL;
if (index >= event->index_nr)
return -EINVAL;
handler->event = event;
handler->flags = 0;
handler->types = types;
handler->index = index;
handler->func = func;
handler->priv = priv;
spin_lock_irqsave(&event->list_lock, flags);
list_add_tail(&handler->head, &event->list[index]);
spin_unlock_irqrestore(&event->list_lock, flags);
return 0;
}
int
nouveau_event_new(struct nouveau_event *event, u32 types, int index,
int (*func)(void *, u32, int), void *priv,
struct nouveau_eventh **phandler)
{
struct nouveau_eventh *handler;
int ret = -ENOMEM;
if (event->check) {
ret = event->check(event, types, index);
if (ret)
return ret;
}
handler = *phandler = kmalloc(sizeof(*handler), GFP_KERNEL);
if (handler) {
ret = nouveau_event_init(event, types, 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, u32 types, int index)
nvkm_event_send(struct nvkm_event *event, u32 types, int index,
void *data, u32 size)
{
struct nouveau_eventh *handler;
struct nvkm_notify *notify;
unsigned long flags;
if (WARN_ON(index >= event->index_nr))
if (!event->refs || WARN_ON(index >= event->index_nr))
return;
spin_lock_irqsave(&event->list_lock, flags);
list_for_each_entry(handler, &event->list[index], head) {
if (!test_bit(NVKM_EVENT_ENABLE, &handler->flags))
continue;
if (!(handler->types & types))
continue;
if (handler->func(handler->priv, handler->types & types, index)
!= NVKM_EVENT_DROP)
continue;
nouveau_event_put(handler);
list_for_each_entry(notify, &event->list, head) {
if (notify->index == index && (notify->types & types)) {
if (event->func->send) {
event->func->send(data, size, notify);
continue;
}
nvkm_notify_send(notify, data, size);
}
}
spin_unlock_irqrestore(&event->list_lock, flags);
}
void
nouveau_event_destroy(struct nouveau_event **pevent)
nvkm_event_fini(struct nvkm_event *event)
{
struct nouveau_event *event = *pevent;
if (event) {
kfree(event);
*pevent = NULL;
if (event->refs) {
kfree(event->refs);
event->refs = NULL;
}
}
int
nouveau_event_create(int types_nr, int index_nr, struct nouveau_event **pevent)
nvkm_event_init(const struct nvkm_event_func *func, int types_nr, int index_nr,
struct nvkm_event *event)
{
struct nouveau_event *event;
int i;
event = *pevent = kzalloc(sizeof(*event) + (index_nr * types_nr) *
sizeof(event->refs[0]), GFP_KERNEL);
if (!event)
return -ENOMEM;
event->list = kmalloc(sizeof(*event->list) * index_nr, GFP_KERNEL);
if (!event->list) {
kfree(event);
event->refs = kzalloc(sizeof(*event->refs) * index_nr * types_nr,
GFP_KERNEL);
if (!event->refs)
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->list[i]);
event->func = func;
event->types_nr = types_nr;
event->index_nr = index_nr;
spin_lock_init(&event->refs_lock);
spin_lock_init(&event->list_lock);
INIT_LIST_HEAD(&event->list);
return 0;
}
......@@ -146,9 +146,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
}
hprintk(handle, TRACE, "created\n");
*phandle = handle;
return 0;
}
......@@ -224,3 +222,116 @@ nouveau_handle_put(struct nouveau_handle *handle)
if (handle)
nouveau_namedb_put(handle);
}
int
nouveau_handle_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_handle_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;
}
This diff is collapsed.
/*
* Copyright 2014 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/client.h>
#include <core/event.h>
#include <core/notify.h>
#include <nvif/unpack.h>
#include <nvif/event.h>
static inline void
nvkm_notify_put_locked(struct nvkm_notify *notify)
{
if (notify->block++ == 0)
nvkm_event_put(notify->event, notify->types, notify->index);
}
void
nvkm_notify_put(struct nvkm_notify *notify)
{
struct nvkm_event *event = notify->event;
unsigned long flags;
if (likely(event) &&
test_and_clear_bit(NVKM_NOTIFY_USER, &notify->flags)) {
spin_lock_irqsave(&event->refs_lock, flags);
nvkm_notify_put_locked(notify);
spin_unlock_irqrestore(&event->refs_lock, flags);
if (test_bit(NVKM_NOTIFY_WORK, &notify->flags))
flush_work(&notify->work);
}
}
static inline void
nvkm_notify_get_locked(struct nvkm_notify *notify)
{
if (--notify->block == 0)
nvkm_event_get(notify->event, notify->types, notify->index);
}
void
nvkm_notify_get(struct nvkm_notify *notify)
{
struct nvkm_event *event = notify->event;
unsigned long flags;
if (likely(event) &&
!test_and_set_bit(NVKM_NOTIFY_USER, &notify->flags)) {
spin_lock_irqsave(&event->refs_lock, flags);
nvkm_notify_get_locked(notify);
spin_unlock_irqrestore(&event->refs_lock, flags);
}
}
static inline void
nvkm_notify_func(struct nvkm_notify *notify)
{
struct nvkm_event *event = notify->event;
int ret = notify->func(notify);
unsigned long flags;
if ((ret == NVKM_NOTIFY_KEEP) ||
!test_and_clear_bit(NVKM_NOTIFY_USER, &notify->flags)) {
spin_lock_irqsave(&event->refs_lock, flags);
nvkm_notify_get_locked(notify);
spin_unlock_irqrestore(&event->refs_lock, flags);
}
}
static void
nvkm_notify_work(struct work_struct *work)
{
struct nvkm_notify *notify = container_of(work, typeof(*notify), work);
nvkm_notify_func(notify);
}
void
nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size)
{
struct nvkm_event *event = notify->event;
unsigned long flags;
BUG_ON(!spin_is_locked(&event->list_lock));
BUG_ON(size != notify->size);
spin_lock_irqsave(&event->refs_lock, flags);
if (notify->block) {
spin_unlock_irqrestore(&event->refs_lock, flags);
return;
}
nvkm_notify_put_locked(notify);
spin_unlock_irqrestore(&event->refs_lock, flags);
if (test_bit(NVKM_NOTIFY_WORK, &notify->flags)) {
memcpy((void *)notify->data, data, size);
schedule_work(&notify->work);
} else {
notify->data = data;
nvkm_notify_func(notify);
notify->data = NULL;
}
}
void
nvkm_notify_fini(struct nvkm_notify *notify)
{
unsigned long flags;
if (notify->event) {
nvkm_notify_put(notify);
spin_lock_irqsave(&notify->event->list_lock, flags);
list_del(&notify->head);
spin_unlock_irqrestore(&notify->event->list_lock, flags);
kfree((void *)notify->data);
notify->event = NULL;
}
}
int
nvkm_notify_init(struct nvkm_event *event, int (*func)(struct nvkm_notify *),
bool work, void *data, u32 size, u32 reply,
struct nvkm_notify *notify)
{
unsigned long flags;
int ret = -ENODEV;
if ((notify->event = event), event->refs) {
ret = event->func->ctor(data, size, notify);
if (ret == 0 && (ret = -EINVAL, notify->size == reply)) {
notify->flags = 0;
notify->block = 1;
notify->func = func;
notify->data = NULL;
if (ret = 0, work) {
INIT_WORK(&notify->work, nvkm_notify_work);
set_bit(NVKM_NOTIFY_WORK, &notify->flags);
notify->data = kmalloc(reply, GFP_KERNEL);
if (!notify->data)
ret = -ENOMEM;
}
}
if (ret == 0) {
spin_lock_irqsave(&event->list_lock, flags);
list_add_tail(&notify->head, &event->list);
spin_unlock_irqrestore(&event->list_lock, flags);
}
}
if (ret)
notify->event = NULL;
return ret;
}
......@@ -23,9 +23,6 @@
*/
#include <core/object.h>
#include <core/parent.h>
#include <core/namedb.h>
#include <core/handle.h>
#include <core/engine.h>
#ifdef NOUVEAU_OBJECT_MAGIC
......@@ -61,21 +58,15 @@ nouveau_object_create_(struct nouveau_object *parent,
return 0;
}
static int
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;
if (size != 0)
return -ENOSYS;
return nouveau_object_create(parent, engine, oclass, 0, pobject);
}
void
......@@ -91,42 +82,24 @@ nouveau_object_destroy(struct nouveau_object *object)
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,
.dtor = nouveau_object_destroy,
.init = nouveau_object_init,
.fini = nouveau_object_fini,
};
int
......@@ -188,119 +161,6 @@ nouveau_object_ref(struct nouveau_object *obj, struct nouveau_object **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)
{
......
......@@ -74,6 +74,39 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
return -EINVAL;
}
int
nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
{
struct nouveau_sclass *sclass;
struct nouveau_engine *engine;
struct nouveau_oclass *oclass;
int nr = -1, i;
u64 mask;
sclass = nv_parent(parent)->sclass;
while (sclass) {
if (++nr < size)
lclass[nr] = sclass->oclass->handle;
sclass = sclass->sclass;
}
mask = nv_parent(parent)->engine;
while (i = __ffs64(mask), mask) {
engine = nouveau_engine(parent, i);
if (engine && (oclass = engine->sclass)) {
while (oclass->ofuncs) {
if (++nr < size)
lclass[nr] = oclass->handle;
oclass++;
}
}
mask &= ~(1ULL << i);
}
return nr + 1;
}
int
nouveau_parent_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
......
......@@ -30,7 +30,6 @@
#include <subdev/vm.h>
#include <core/client.h>
#include <core/class.h>
#include <core/enum.h>
......
......@@ -26,9 +26,7 @@
#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"
......
......@@ -24,7 +24,6 @@
#include <core/os.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
#include <engine/copy.h>
......
......@@ -25,7 +25,6 @@
#include <core/client.h>
#include <core/os.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
#include <core/gpuobj.h>
......
......@@ -25,7 +25,6 @@
#include <core/client.h>
#include <core/os.h>
#include <core/enum.h>
#include <core/class.h>
#include <core/engctx.h>
#include <subdev/timer.h>
......
/*
* Copyright 2014 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 "acpi.h"
#ifdef CONFIG_ACPI
static int
nvkm_acpi_ntfy(struct notifier_block *nb, unsigned long val, void *data)
{
struct nouveau_device *device =
container_of(nb, typeof(*device), acpi.nb);
struct acpi_bus_event *info = data;
if (!strcmp(info->device_class, "ac_adapter"))
nvkm_event_send(&device->event, 1, 0, NULL, 0);
return NOTIFY_DONE;
}
#endif
int
nvkm_acpi_fini(struct nouveau_device *device, bool suspend)
{
#ifdef CONFIG_ACPI
unregister_acpi_notifier(&device->acpi.nb);
#endif
return 0;
}
int
nvkm_acpi_init(struct nouveau_device *device)
{
#ifdef CONFIG_ACPI
device->acpi.nb.notifier_call = nvkm_acpi_ntfy;
register_acpi_notifier(&device->acpi.nb);
#endif
return 0;
}
#ifndef __NVKM_DEVICE_ACPI_H__
#define __NVKM_DEVICE_ACPI_H__
#include <engine/device.h>
int nvkm_acpi_init(struct nouveau_device *);
int nvkm_acpi_fini(struct nouveau_device *, bool);
#endif
......@@ -22,55 +22,82 @@
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
#include <core/client.h>
#include <core/object.h>
#include <core/class.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <nvif/ioctl.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)
nouveau_control_mthd_pstate_info(struct nouveau_object *object,
void *data, u32 size)
{
union {
struct nvif_control_pstate_info_v0 v0;
} *args = data;
struct nouveau_clock *clk = nouveau_clock(object);
struct nv_control_pstate_info *args = data;
int ret;
if (size < sizeof(*args))
return -EINVAL;
nv_ioctl(object, "control pstate info size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "control pstate info vers %d\n",
args->v0.version);
} else
return ret;
if (clk) {
args->count = clk->state_nr;
args->ustate = clk->ustate;
args->pstate = clk->pstate;
args->v0.count = clk->state_nr;
args->v0.ustate_ac = clk->ustate_ac;
args->v0.ustate_dc = clk->ustate_dc;
args->v0.pwrsrc = clk->pwrsrc;
args->v0.pstate = clk->pstate;
} else {
args->count = 0;
args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE;
args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN;
args->v0.count = 0;
args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
args->v0.ustate_dc = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE;
args->v0.pwrsrc = -ENOSYS;
args->v0.pstate = NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN;
}
return 0;
}
static int
nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
nouveau_control_mthd_pstate_attr(struct nouveau_object *object,
void *data, u32 size)
{
union {
struct nvif_control_pstate_attr_v0 v0;
} *args = data;
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;
int ret;
nv_ioctl(object, "control pstate attr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "control pstate attr vers %d state %d "
"index %d\n",
args->v0.version, args->v0.state, args->v0.index);
if (!clk)
return -ENODEV;
if (args->v0.state < NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT)
return -EINVAL;
if (args->v0.state >= clk->state_nr)
return -EINVAL;
} else
return ret;
domain = clk->domains;
while (domain->name != nv_clk_src_max) {
if (domain->mname && ++j == args->index)
if (domain->mname && ++j == args->v0.index)
break;
domain++;
}
......@@ -78,9 +105,9 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd,
if (domain->name == nv_clk_src_max)
return -EINVAL;
if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) {
if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) {
list_for_each_entry(pstate, &clk->states, head) {
if (i++ == args->state)
if (i++ == args->v0.state)
break;
}
......@@ -91,21 +118,21 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd,
hi = max(hi, cstate->domain[domain->name]);
}
args->state = pstate->pstate;
args->v0.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;
snprintf(args->v0.name, sizeof(args->v0.name), "%s", domain->mname);
snprintf(args->v0.unit, sizeof(args->v0.unit), "MHz");
args->v0.min = lo / domain->mdiv;
args->v0.max = hi / domain->mdiv;
args->index = 0;
args->v0.index = 0;
while ((++domain)->name != nv_clk_src_max) {
if (domain->mname) {
args->index = ++j;
args->v0.index = ++j;
break;
}
}
......@@ -114,31 +141,65 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd,
}
static int
nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
nouveau_control_mthd_pstate_user(struct nouveau_object *object,
void *data, u32 size)
{
union {
struct nvif_control_pstate_user_v0 v0;
} *args = data;
struct nouveau_clock *clk = nouveau_clock(object);
struct nv_control_pstate_user *args = data;
int ret;
nv_ioctl(object, "control pstate user size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "control pstate user vers %d ustate %d "
"pwrsrc %d\n", args->v0.version,
args->v0.ustate, args->v0.pwrsrc);
if (!clk)
return -ENODEV;
} else
return ret;
if (args->v0.pwrsrc >= 0) {
ret |= nouveau_clock_ustate(clk, args->v0.ustate, args->v0.pwrsrc);
} else {
ret |= nouveau_clock_ustate(clk, args->v0.ustate, 0);
ret |= nouveau_clock_ustate(clk, args->v0.ustate, 1);
}
if (size < sizeof(*args) || !clk)
return -EINVAL;
return ret;
}
return nouveau_clock_ustate(clk, args->state);
static int
nouveau_control_mthd(struct nouveau_object *object, u32 mthd,
void *data, u32 size)
{
switch (mthd) {
case NVIF_CONTROL_PSTATE_INFO:
return nouveau_control_mthd_pstate_info(object, data, size);
case NVIF_CONTROL_PSTATE_ATTR:
return nouveau_control_mthd_pstate_attr(object, data, size);
case NVIF_CONTROL_PSTATE_USER:
return nouveau_control_mthd_pstate_user(object, data, size);
default:
break;
}
return -EINVAL;
}
static struct nouveau_ofuncs
nouveau_control_ofuncs = {
.ctor = _nouveau_object_ctor,
.dtor = nouveau_object_destroy,
.init = nouveau_object_init,
.fini = nouveau_object_fini,
.mthd = nouveau_control_mthd,
};
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 },
{},
},
{ .handle = NVIF_IOCTL_NEW_V0_CONTROL,
.ofuncs = &nouveau_control_ofuncs
},
{}
};
......@@ -33,7 +33,7 @@
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/ltcg.h>
#include <subdev/ltc.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
......@@ -68,20 +68,20 @@ gm100_identify(struct nouveau_device *device)
#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_MC ] = gk20a_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_LTC ] = gm107_ltc_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_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_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;
......
......@@ -56,7 +56,7 @@ nv04_identify(struct nouveau_device *device)
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_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;
......@@ -74,7 +74,7 @@ nv04_identify(struct nouveau_device *device)
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_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;
......
......@@ -58,7 +58,7 @@ nv10_identify(struct nouveau_device *device)
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_DMAOBJ ] = nv04_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass;
device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass;
break;
......@@ -75,7 +75,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......@@ -94,7 +94,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......@@ -113,7 +113,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......@@ -132,7 +132,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......@@ -151,7 +151,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......@@ -170,7 +170,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......@@ -189,7 +189,7 @@ nv10_identify(struct nouveau_device *device)
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_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;
......
......@@ -59,7 +59,7 @@ nv20_identify(struct nouveau_device *device)
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_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;
......@@ -78,7 +78,7 @@ nv20_identify(struct nouveau_device *device)
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_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;
......@@ -97,7 +97,7 @@ nv20_identify(struct nouveau_device *device)
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_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;
......@@ -116,7 +116,7 @@ nv20_identify(struct nouveau_device *device)
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_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;
......
......@@ -59,7 +59,7 @@ nv30_identify(struct nouveau_device *device)
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_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;
......@@ -78,7 +78,7 @@ nv30_identify(struct nouveau_device *device)
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_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;
......@@ -97,7 +97,7 @@ nv30_identify(struct nouveau_device *device)
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_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;
......@@ -117,7 +117,7 @@ nv30_identify(struct nouveau_device *device)
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_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;
......@@ -137,7 +137,7 @@ nv30_identify(struct nouveau_device *device)
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_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;
......
......@@ -65,7 +65,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -88,7 +88,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -111,7 +111,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -134,7 +134,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -157,7 +157,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -180,7 +180,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -203,7 +203,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -226,7 +226,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -249,7 +249,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -272,7 +272,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -295,7 +295,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -318,7 +318,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -341,7 +341,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -364,7 +364,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -387,7 +387,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......@@ -410,7 +410,7 @@ nv40_identify(struct nouveau_device *device)
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_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;
......
......@@ -74,7 +74,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -99,7 +99,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -127,7 +127,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -155,7 +155,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -183,7 +183,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -211,7 +211,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -239,7 +239,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -267,7 +267,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -295,7 +295,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -323,7 +323,7 @@ nv50_identify(struct nouveau_device *device)
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_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;
......@@ -350,9 +350,9 @@ nv50_identify(struct nouveau_device *device)
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_PWR ] = nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_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;
......@@ -380,9 +380,9 @@ nv50_identify(struct nouveau_device *device)
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_PWR ] = nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_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;
......@@ -409,9 +409,9 @@ nv50_identify(struct nouveau_device *device)
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_PWR ] = nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_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;
......@@ -438,9 +438,9 @@ nv50_identify(struct nouveau_device *device)
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_PWR ] = nva3_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_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;
......
......@@ -33,7 +33,7 @@
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/ltcg.h>
#include <subdev/ltc.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
......@@ -70,14 +70,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -102,14 +102,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -134,14 +134,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -165,14 +165,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -197,14 +197,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -229,14 +229,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -260,14 +260,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvc0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_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;
......@@ -292,14 +292,14 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_PWR ] = nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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;
......@@ -323,12 +323,12 @@ nvc0_identify(struct nouveau_device *device)
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_LTC ] = gf100_ltc_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_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;
......
......@@ -33,7 +33,7 @@
#include <subdev/mc.h>
#include <subdev/timer.h>
#include <subdev/fb.h>
#include <subdev/ltcg.h>
#include <subdev/ltc.h>
#include <subdev/ibus.h>
#include <subdev/instmem.h>
#include <subdev/vm.h>
......@@ -70,14 +70,14 @@ nve0_identify(struct nouveau_device *device)
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_LTC ] = gk104_ltc_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_PWR ] = gk104_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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;
......@@ -103,14 +103,14 @@ nve0_identify(struct nouveau_device *device)
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_LTC ] = gk104_ltc_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_PWR ] = nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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;
......@@ -136,14 +136,14 @@ nve0_identify(struct nouveau_device *device)
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_LTC ] = gk104_ltc_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_PWR ] = gk104_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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;
......@@ -158,15 +158,16 @@ nve0_identify(struct nouveau_device *device)
break;
case 0xea:
device->cname = "GK20A";
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
device->oclass[NVDEV_SUBDEV_CLOCK ] = &gk20a_clock_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_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_SUBDEV_BAR ] = &gk20a_bar_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass;
......@@ -186,14 +187,14 @@ nve0_identify(struct nouveau_device *device)
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_LTC ] = gk104_ltc_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_PWR ] = nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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;
......@@ -219,17 +220,17 @@ nve0_identify(struct nouveau_device *device)
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_LTC ] = gk104_ltc_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_PWR ] = nvd0_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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_GR ] = gk110b_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;
......@@ -248,18 +249,18 @@ nve0_identify(struct nouveau_device *device)
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_MC ] = gk20a_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_LTC ] = gk104_ltc_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_PWR ] = nv108_pwr_oclass;
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_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;
......
......@@ -22,23 +22,93 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <nvif/event.h>
#include "priv.h"
#include "outp.h"
#include "conn.h"
int
nouveau_disp_vblank_ctor(void *data, u32 size, struct nvkm_notify *notify)
{
struct nouveau_disp *disp =
container_of(notify->event, typeof(*disp), vblank);
union {
struct nvif_notify_head_req_v0 v0;
} *req = data;
int ret;
if (nvif_unpack(req->v0, 0, 0, false)) {
notify->size = sizeof(struct nvif_notify_head_rep_v0);
if (ret = -ENXIO, req->v0.head <= disp->vblank.index_nr) {
notify->types = 1;
notify->index = req->v0.head;
return 0;
}
}
return ret;
}
void
nouveau_disp_vblank(struct nouveau_disp *disp, int head)
{
struct nvif_notify_head_rep_v0 rep = {};
nvkm_event_send(&disp->vblank, 1, head, &rep, sizeof(rep));
}
static int
nouveau_disp_hpd_check(struct nouveau_event *event, u32 types, int index)
nouveau_disp_hpd_ctor(void *data, u32 size, struct nvkm_notify *notify)
{
struct nouveau_disp *disp = event->priv;
struct nouveau_disp *disp =
container_of(notify->event, typeof(*disp), hpd);
union {
struct nvif_notify_conn_req_v0 v0;
} *req = data;
struct nvkm_output *outp;
list_for_each_entry(outp, &disp->outp, head) {
if (outp->conn->index == index) {
if (outp->conn->hpd.event)
return 0;
break;
int ret;
if (nvif_unpack(req->v0, 0, 0, false)) {
notify->size = sizeof(struct nvif_notify_conn_rep_v0);
list_for_each_entry(outp, &disp->outp, head) {
if (ret = -ENXIO, outp->conn->index == req->v0.conn) {
if (ret = -ENODEV, outp->conn->hpd.event) {
notify->types = req->v0.mask;
notify->index = req->v0.conn;
ret = 0;
}
break;
}
}
}
return -ENOSYS;
return ret;
}
static const struct nvkm_event_func
nouveau_disp_hpd_func = {
.ctor = nouveau_disp_hpd_ctor
};
int
nouveau_disp_ntfy(struct nouveau_object *object, u32 type,
struct nvkm_event **event)
{
struct nouveau_disp *disp = (void *)object->engine;
switch (type) {
case NV04_DISP_NTFY_VBLANK:
*event = &disp->vblank;
return 0;
case NV04_DISP_NTFY_CONN:
*event = &disp->hpd;
return 0;
default:
break;
}
return -EINVAL;
}
int
......@@ -97,7 +167,8 @@ _nouveau_disp_dtor(struct nouveau_object *object)
struct nouveau_disp *disp = (void *)object;
struct nvkm_output *outp, *outt;
nouveau_event_destroy(&disp->vblank);
nvkm_event_fini(&disp->vblank);
nvkm_event_fini(&disp->hpd);
if (disp->outp.next) {
list_for_each_entry_safe(outp, outt, &disp->outp, head) {
......@@ -157,14 +228,11 @@ nouveau_disp_create_(struct nouveau_object *parent,
hpd = max(hpd, (u8)(dcbE.connector + 1));
}
ret = nouveau_event_create(3, hpd, &disp->hpd);
ret = nvkm_event_init(&nouveau_disp_hpd_func, 3, hpd, &disp->hpd);
if (ret)
return ret;
disp->hpd->priv = disp;
disp->hpd->check = nouveau_disp_hpd_check;
ret = nouveau_event_create(1, heads, &disp->vblank);
ret = nvkm_event_init(impl->vblank, 1, heads, &disp->vblank);
if (ret)
return ret;
......
......@@ -22,39 +22,41 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <nvif/event.h>
#include <subdev/gpio.h>
#include "conn.h"
#include "outp.h"
static void
nvkm_connector_hpd_work(struct work_struct *w)
static int
nvkm_connector_hpd(struct nvkm_notify *notify)
{
struct nvkm_connector *conn = container_of(w, typeof(*conn), hpd.work);
struct nvkm_connector *conn = container_of(notify, typeof(*conn), hpd);
struct nouveau_disp *disp = nouveau_disp(conn);
struct nouveau_gpio *gpio = nouveau_gpio(conn);
u32 send = NVKM_HPD_UNPLUG;
if (gpio->get(gpio, 0, DCB_GPIO_UNUSED, conn->hpd.event->index))
send = NVKM_HPD_PLUG;
nouveau_event_trigger(disp->hpd, send, conn->index);
nouveau_event_get(conn->hpd.event);
}
const struct nvkm_gpio_ntfy_rep *line = notify->data;
struct nvif_notify_conn_rep_v0 rep;
int index = conn->index;
static int
nvkm_connector_hpd(void *data, u32 type, int index)
{
struct nvkm_connector *conn = data;
DBG("HPD: %d\n", type);
schedule_work(&conn->hpd.work);
return NVKM_EVENT_DROP;
DBG("HPD: %d\n", line->mask);
if (!gpio->get(gpio, 0, DCB_GPIO_UNUSED, conn->hpd.index))
rep.mask = NVIF_NOTIFY_CONN_V0_UNPLUG;
else
rep.mask = NVIF_NOTIFY_CONN_V0_PLUG;
rep.version = 0;
nvkm_event_send(&disp->hpd, rep.mask, index, &rep, sizeof(rep));
return NVKM_NOTIFY_KEEP;
}
int
_nvkm_connector_fini(struct nouveau_object *object, bool suspend)
{
struct nvkm_connector *conn = (void *)object;
if (conn->hpd.event)
nouveau_event_put(conn->hpd.event);
nvkm_notify_put(&conn->hpd);
return nouveau_object_fini(&conn->base, suspend);
}
......@@ -63,10 +65,8 @@ _nvkm_connector_init(struct nouveau_object *object)
{
struct nvkm_connector *conn = (void *)object;
int ret = nouveau_object_init(&conn->base);
if (ret == 0) {
if (conn->hpd.event)
nouveau_event_get(conn->hpd.event);
}
if (ret == 0)
nvkm_notify_get(&conn->hpd);
return ret;
}
......@@ -74,7 +74,7 @@ void
_nvkm_connector_dtor(struct nouveau_object *object)
{
struct nvkm_connector *conn = (void *)object;
nouveau_event_ref(NULL, &conn->hpd.event);
nvkm_notify_fini(&conn->hpd);
nouveau_object_destroy(&conn->base);
}
......@@ -116,19 +116,24 @@ nvkm_connector_create_(struct nouveau_object *parent,
if ((info->hpd = ffs(info->hpd))) {
if (--info->hpd >= ARRAY_SIZE(hpd)) {
ERR("hpd %02x unknown\n", info->hpd);
goto done;
return 0;
}
info->hpd = hpd[info->hpd];
ret = gpio->find(gpio, 0, info->hpd, DCB_GPIO_UNUSED, &func);
if (ret) {
ERR("func %02x lookup failed, %d\n", info->hpd, ret);
goto done;
return 0;
}
ret = nouveau_event_new(gpio->events, NVKM_GPIO_TOGGLED,
func.line, nvkm_connector_hpd,
conn, &conn->hpd.event);
ret = nvkm_notify_init(&gpio->event, nvkm_connector_hpd, true,
&(struct nvkm_gpio_ntfy_req) {
.mask = NVKM_GPIO_TOGGLED,
.line = func.line,
},
sizeof(struct nvkm_gpio_ntfy_req),
sizeof(struct nvkm_gpio_ntfy_rep),
&conn->hpd);
if (ret) {
ERR("func %02x failed, %d\n", info->hpd, ret);
} else {
......@@ -136,8 +141,6 @@ nvkm_connector_create_(struct nouveau_object *parent,
}
}
done:
INIT_WORK(&conn->hpd.work, nvkm_connector_hpd_work);
return 0;
}
......
......@@ -10,10 +10,7 @@ struct nvkm_connector {
struct nvbios_connE info;
int index;
struct {
struct nouveau_eventh *event;
struct work_struct work;
} hpd;
struct nvkm_notify hpd;
};
#define nvkm_connector_create(p,e,c,b,i,d) \
......
......@@ -22,8 +22,9 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
......@@ -32,13 +33,28 @@
#include "nv50.h"
int
nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data)
nv50_dac_power(NV50_DISP_MTHD_V1)
{
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);
const u32 doff = outp->or * 0x800;
union {
struct nv50_disp_dac_pwr_v0 v0;
} *args = data;
u32 stat;
int ret;
nv_ioctl(object, "disp dac pwr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "disp dac pwr vers %d state %d data %d "
"vsync %d hsync %d\n",
args->v0.version, args->v0.state, args->v0.data,
args->v0.vsync, args->v0.hsync);
stat = 0x00000040 * !args->v0.state;
stat |= 0x00000010 * !args->v0.data;
stat |= 0x00000004 * !args->v0.vsync;
stat |= 0x00000001 * !args->v0.hsync;
} else
return ret;
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
nv_mask(priv, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat);
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
......@@ -46,9 +62,24 @@ nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data)
}
int
nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
nv50_dac_sense(NV50_DISP_MTHD_V1)
{
const u32 doff = (or * 0x800);
union {
struct nv50_disp_dac_load_v0 v0;
} *args = data;
const u32 doff = outp->or * 0x800;
u32 loadval;
int ret;
nv_ioctl(object, "disp dac load size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "disp dac load vers %d data %08x\n",
args->v0.version, args->v0.data);
if (args->v0.data & 0xfff00000)
return -EINVAL;
loadval = args->v0.data;
} else
return ret;
nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000);
nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000);
......@@ -61,38 +92,10 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval)
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);
nv_debug(priv, "DAC%d sense: 0x%08x\n", outp->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;
args->v0.load = (loadval & 0x38000000) >> 27;
return 0;
}
......@@ -30,7 +30,7 @@
#include <engine/disp.h>
#include <core/class.h>
#include <nvif/class.h>
#include "dport.h"
#include "outpdp.h"
......@@ -335,7 +335,7 @@ nouveau_dp_train(struct work_struct *w)
int ret;
/* bring capabilities within encoder limits */
if (nv_mclass(disp) < NVD0_DISP_CLASS)
if (nv_mclass(disp) < GF110_DISP)
outp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED;
if ((outp->dpcd[2] & 0x1f) > outp->base.info.dpconf.link_nr) {
outp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT;
......@@ -354,7 +354,7 @@ nouveau_dp_train(struct work_struct *w)
cfg--;
/* disable link interrupt handling during link training */
nouveau_event_put(outp->irq);
nvkm_notify_put(&outp->irq);
/* enable down-spreading and execute pre-train script from vbios */
dp_link_train_init(dp, outp->dpcd[3] & 0x01);
......@@ -395,5 +395,5 @@ nouveau_dp_train(struct work_struct *w)
DBG("training complete\n");
atomic_set(&outp->lt.done, 1);
wake_up(&outp->lt.wait);
nouveau_event_get(outp->irq);
nvkm_notify_get(&outp->irq);
}
......@@ -25,7 +25,7 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include <nvif/class.h>
#include "nv50.h"
......@@ -35,17 +35,17 @@
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 },
{ GM107_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base },
{ GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base },
{ GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
{ GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
{ GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
{}
};
static struct nouveau_oclass
gm107_disp_base_oclass[] = {
{ GM107_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds },
{ GM107_DISP, &nvd0_disp_base_ofuncs },
{}
};
......@@ -93,9 +93,11 @@ gm107_disp_oclass = &(struct nv50_disp_impl) {
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.base.vblank = &nvd0_disp_vblank_func,
.base.outp = nvd0_disp_outp_sclass,
.mthd.core = &nve0_disp_mast_mthd_chan,
.mthd.base = &nvd0_disp_sync_mthd_chan,
.mthd.ovly = &nve0_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
.head.scanoutpos = nvd0_disp_base_scanoutpos,
}.base.base;
......@@ -22,25 +22,37 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include "nv50.h"
int
nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size)
nva3_hda_eld(NV50_DISP_MTHD_V1)
{
const u32 soff = (or * 0x800);
int i;
union {
struct nv50_disp_sor_hda_eld_v0 v0;
} *args = data;
const u32 soff = outp->or * 0x800;
int ret, i;
if (data && data[0]) {
nv_ioctl(object, "disp sor hda eld size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version);
if (size > 0x60)
return -E2BIG;
} else
return ret;
if (size && args->v0.data[0]) {
for (i = 0; i < size; i++)
nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]);
nv_wr32(priv, 0x61c440 + soff, (i << 8) | args->v0.data[0]);
for (; i < 0x60; i++)
nv_wr32(priv, 0x61c440 + soff, (i << 8));
nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003);
} else
if (data) {
if (size) {
nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000001);
} else {
nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000000);
......
......@@ -22,8 +22,9 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include <subdev/bios.h>
#include <subdev/bios/dcb.h>
......@@ -33,19 +34,30 @@
#include "nv50.h"
int
nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size)
nvd0_hda_eld(NV50_DISP_MTHD_V1)
{
const u32 soff = (or * 0x030);
int i;
union {
struct nv50_disp_sor_hda_eld_v0 v0;
} *args = data;
const u32 soff = outp->or * 0x030;
int ret, i;
if (data && data[0]) {
nv_ioctl(object, "disp sor hda eld size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version);
if (size > 0x60)
return -E2BIG;
} else
return ret;
if (size && args->v0.data[0]) {
for (i = 0; i < size; i++)
nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]);
nv_wr32(priv, 0x10ec00 + soff, (i << 8) | args->v0.data[i]);
for (; i < 0x60; i++)
nv_wr32(priv, 0x10ec00 + soff, (i << 8));
nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003);
} else
if (data) {
if (size) {
nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001);
} else {
nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000);
......
......@@ -22,17 +22,38 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include "nv50.h"
int
nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
nv84_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 hoff = (head * 0x800);
union {
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) {
nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
args->v0.max_ac_packet, args->v0.rekey);
if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f)
return -EINVAL;
ctrl = 0x40000000 * !!args->v0.state;
ctrl |= args->v0.max_ac_packet << 16;
ctrl |= args->v0.rekey;
ctrl |= 0x1f000000; /* ??? */
} else
return ret;
if (!(ctrl & 0x40000000)) {
nv_mask(priv, 0x6165a4 + hoff, 0x40000000, 0x00000000);
nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000000);
nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000000);
......@@ -65,6 +86,6 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
/* HDMI_CTRL */
nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, data | 0x1f000000 /* ??? */);
nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, ctrl);
return 0;
}
......@@ -22,17 +22,38 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include "nv50.h"
int
nva3_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
nva3_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 soff = (or * 0x800);
const u32 soff = outp->or * 0x800;
union {
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) {
nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
args->v0.max_ac_packet, args->v0.rekey);
if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f)
return -EINVAL;
ctrl = 0x40000000 * !!args->v0.state;
ctrl |= args->v0.max_ac_packet << 16;
ctrl |= args->v0.rekey;
ctrl |= 0x1f000000; /* ??? */
} else
return ret;
if (!(ctrl & 0x40000000)) {
nv_mask(priv, 0x61c5a4 + soff, 0x40000000, 0x00000000);
nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000000);
nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000000);
......@@ -65,6 +86,6 @@ nva3_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */
/* HDMI_CTRL */
nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, data | 0x1f000000 /* ??? */);
nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, ctrl);
return 0;
}
......@@ -22,17 +22,37 @@
* Authors: Ben Skeggs
*/
#include <core/os.h>
#include <core/class.h>
#include <core/client.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
#include "nv50.h"
int
nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1)
{
const u32 hoff = (head * 0x800);
union {
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) {
nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
args->v0.max_ac_packet, args->v0.rekey);
if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f)
return -EINVAL;
ctrl = 0x40000000 * !!args->v0.state;
ctrl |= args->v0.max_ac_packet << 16;
ctrl |= args->v0.rekey;
} else
return ret;
if (!(ctrl & 0x40000000)) {
nv_mask(priv, 0x616798 + hoff, 0x40000000, 0x00000000);
nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000);
nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000);
......@@ -54,7 +74,7 @@ nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data)
nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000001);
/* HDMI_CTRL */
nv_mask(priv, 0x616798 + hoff, 0x401f007f, data);
nv_mask(priv, 0x616798 + hoff, 0x401f007f, ctrl);
/* NFI, audio doesn't work without it though.. */
nv_mask(priv, 0x616548 + hoff, 0x00000070, 0x00000000);
......
......@@ -24,60 +24,100 @@
#include "priv.h"
#include <core/client.h>
#include <core/event.h>
#include <core/class.h>
#include <nvif/unpack.h>
#include <nvif/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)
nv04_disp_scanoutpos(struct nouveau_object *object, struct nv04_disp_priv *priv,
void *data, u32 size, int head)
{
struct nv04_disp_priv *priv = (void *)object->engine;
struct nv04_display_scanoutpos *args = data;
const int head = (mthd & NV04_DISP_MTHD_HEAD);
const u32 hoff = head * 0x2000;
union {
struct nv04_disp_scanoutpos_v0 v0;
} *args = data;
u32 line;
int ret;
nv_ioctl(object, "disp scanoutpos size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nv_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version);
args->v0.vblanks = nv_rd32(priv, 0x680800 + hoff) & 0xffff;
args->v0.vtotal = nv_rd32(priv, 0x680804 + hoff) & 0xffff;
args->v0.vblanke = args->v0.vtotal - 1;
args->v0.hblanks = nv_rd32(priv, 0x680820 + hoff) & 0xffff;
args->v0.htotal = nv_rd32(priv, 0x680824 + hoff) & 0xffff;
args->v0.hblanke = args->v0.htotal - 1;
/*
* If output is vga instead of digital then vtotal/htotal is
* invalid so we have to give up and trigger the timestamping
* fallback in the drm core.
*/
if (!args->v0.vtotal || !args->v0.htotal)
return -ENOTSUPP;
args->v0.time[0] = ktime_to_ns(ktime_get());
line = nv_rd32(priv, 0x600868 + hoff);
args->v0.time[1] = ktime_to_ns(ktime_get());
args->v0.hline = (line & 0xffff0000) >> 16;
args->v0.vline = (line & 0x0000ffff);
} else
return ret;
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;
/*
* If output is vga instead of digital then vtotal/htotal is invalid
* so we have to give up and trigger the timestamping fallback in the
* drm core.
*/
if (!args->vtotal || !args->htotal)
return -ENOTSUPP;
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 int
nv04_disp_mthd(struct nouveau_object *object, u32 mthd, void *data, u32 size)
{
union {
struct nv04_disp_mthd_v0 v0;
} *args = data;
struct nv04_disp_priv *priv = (void *)object->engine;
int head, ret;
nv_ioctl(object, "disp mthd size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
nv_ioctl(object, "disp mthd vers %d mthd %02x head %d\n",
args->v0.version, args->v0.method, args->v0.head);
mthd = args->v0.method;
head = args->v0.head;
} else
return ret;
static struct nouveau_omthds
nv04_disp_omthds[] = {
{ HEAD_MTHD(NV04_DISP_SCANOUTPOS), nv04_disp_scanoutpos },
{}
if (head < 0 || head >= 2)
return -ENXIO;
switch (mthd) {
case NV04_DISP_SCANOUTPOS:
return nv04_disp_scanoutpos(object, priv, data, size, head);
default:
break;
}
return -EINVAL;
}
static struct nouveau_ofuncs
nv04_disp_ofuncs = {
.ctor = _nouveau_object_ctor,
.dtor = nouveau_object_destroy,
.init = nouveau_object_init,
.fini = nouveau_object_fini,
.mthd = nv04_disp_mthd,
.ntfy = nouveau_disp_ntfy,
};
static struct nouveau_oclass
nv04_disp_sclass[] = {
{ NV04_DISP_CLASS, &nouveau_object_ofuncs, nv04_disp_omthds },
{ NV04_DISP, &nv04_disp_ofuncs },
{},
};
......@@ -86,17 +126,26 @@ nv04_disp_sclass[] = {
******************************************************************************/
static void
nv04_disp_vblank_enable(struct nouveau_event *event, int type, int head)
nv04_disp_vblank_init(struct nvkm_event *event, int type, int head)
{
nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001);
struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
nv_wr32(disp, 0x600140 + (head * 0x2000) , 0x00000001);
}
static void
nv04_disp_vblank_disable(struct nouveau_event *event, int type, int head)
nv04_disp_vblank_fini(struct nvkm_event *event, int type, int head)
{
nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000);
struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank);
nv_wr32(disp, 0x600140 + (head * 0x2000) , 0x00000000);
}
static const struct nvkm_event_func
nv04_disp_vblank_func = {
.ctor = nouveau_disp_vblank_ctor,
.init = nv04_disp_vblank_init,
.fini = nv04_disp_vblank_fini,
};
static void
nv04_disp_intr(struct nouveau_subdev *subdev)
{
......@@ -106,12 +155,12 @@ nv04_disp_intr(struct nouveau_subdev *subdev)
u32 pvideo;
if (crtc0 & 0x00000001) {
nouveau_event_trigger(priv->base.vblank, 1, 0);
nouveau_disp_vblank(&priv->base, 0);
nv_wr32(priv, 0x600100, 0x00000001);
}
if (crtc1 & 0x00000001) {
nouveau_event_trigger(priv->base.vblank, 1, 1);
nouveau_disp_vblank(&priv->base, 1);
nv_wr32(priv, 0x602100, 0x00000001);
}
......@@ -140,9 +189,6 @@ nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
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;
}
......@@ -155,4 +201,5 @@ nv04_disp_oclass = &(struct nouveau_disp_impl) {
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.vblank = &nv04_disp_vblank_func,
}.base;
......@@ -25,7 +25,7 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include <nvif/class.h>
#include "nv50.h"
......@@ -204,31 +204,17 @@ nv84_disp_ovly_mthd_chan = {
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 },
{ G82_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base },
{ G82_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base },
{ G82_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
{ G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
{ G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
{}
};
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 },
{ G82_DISP, &nv50_disp_base_ofuncs },
{}
};
......@@ -276,9 +262,11 @@ nv84_disp_oclass = &(struct nv50_disp_impl) {
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
.base.outp = nv50_disp_outp_sclass,
.mthd.core = &nv84_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nv84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_base_scanoutpos,
}.base.base;
......@@ -25,7 +25,7 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include <nvif/class.h>
#include "nv50.h"
......@@ -63,32 +63,17 @@ nv94_disp_mast_mthd_chan = {
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 },
{ GT206_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base },
{ GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base },
{ GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
{ G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
{ G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
{}
};
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 },
{ SOR_MTHD(NV94_DISP_SOR_DP_PWR) , 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 },
{ GT206_DISP, &nv50_disp_base_ofuncs },
{}
};
......@@ -143,9 +128,11 @@ nv94_disp_oclass = &(struct nv50_disp_impl) {
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
.base.outp = nv94_disp_outp_sclass,
.mthd.core = &nv94_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nv84_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_base_scanoutpos,
}.base.base;
......@@ -25,7 +25,7 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include <nvif/class.h>
#include "nv50.h"
......@@ -80,17 +80,17 @@ nva0_disp_ovly_mthd_chan = {
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 },
{ GT200_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base },
{ GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base },
{ GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
{ G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
{ G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
{}
};
static struct nouveau_oclass
nva0_disp_base_oclass[] = {
{ NVA0_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds },
{ GT200_DISP, &nv50_disp_base_ofuncs },
{}
};
......@@ -138,9 +138,11 @@ nva0_disp_oclass = &(struct nv50_disp_impl) {
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.base.vblank = &nv50_disp_vblank_func,
.base.outp = nv50_disp_outp_sclass,
.mthd.core = &nv84_disp_mast_mthd_chan,
.mthd.base = &nv84_disp_sync_mthd_chan,
.mthd.ovly = &nva0_disp_ovly_mthd_chan,
.mthd.prev = 0x000004,
.head.scanoutpos = nv50_disp_base_scanoutpos,
}.base.base;
......@@ -25,7 +25,7 @@
#include <engine/software.h>
#include <engine/disp.h>
#include <core/class.h>
#include <nvif/class.h>
#include "nv50.h"
......@@ -200,17 +200,17 @@ nve0_disp_ovly_mthd_chan = {
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 },
{ GK104_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base },
{ GK104_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base },
{ GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
{ GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
{ GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
{}
};
static struct nouveau_oclass
nve0_disp_base_oclass[] = {
{ NVE0_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds },
{ GK104_DISP, &nvd0_disp_base_ofuncs },
{}
};
......@@ -258,9 +258,11 @@ nve0_disp_oclass = &(struct nv50_disp_impl) {
.init = _nouveau_disp_init,
.fini = _nouveau_disp_fini,
},
.base.vblank = &nvd0_disp_vblank_func,
.base.outp = nvd0_disp_outp_sclass,
.mthd.core = &nve0_disp_mast_mthd_chan,
.mthd.base = &nvd0_disp_sync_mthd_chan,
.mthd.ovly = &nve0_disp_ovly_mthd_chan,
.mthd.prev = -0x020000,
.head.scanoutpos = nvd0_disp_base_scanoutpos,
}.base.base;
......@@ -78,6 +78,7 @@ nvkm_output_create_(struct nouveau_object *parent,
outp->info = *dcbE;
outp->index = index;
outp->or = ffs(outp->info.or) - 1;
DBG("type %02x loc %d or %d link %d con %x edid %x bus %d head %x\n",
dcbE->type, dcbE->location, dcbE->or, dcbE->type >= 2 ?
......
......@@ -9,6 +9,7 @@ struct nvkm_output {
struct dcb_output info;
int index;
int or;
struct nouveau_i2c_port *port;
struct nouveau_i2c_port *edid;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment