Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
"Nothing overly exciting here aside from calim's fermi/kepler vram compression patches. The rest is misc fixes I gathered from the list. Most of the stuff from me is fixing issues that have come up from the work on kepler PM, as well as a commit moving all the old-school modesetting out of the way (no code changes here). There's other patches to go on top of that, but, it'll have to wait until I can rip out the old PM code, it's a bit tangled." * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (38 commits) drm/nouveau/fifo: implement channel creation event generation drm/nouveau/core: allow non-maskable events drm/nouveau/timer: allow alarms to be cancelled drm/nouveau/device: tweak the device/subdev relationship a little drm/nouveau/device: enable proper constructor/destructor drm/nouveau/device: have engine object initialised before creation drm/nouveau/device: convert to engine, rather than subdev drm/nv50-/disp: use self as parent for subobjects drm/nv50-/fifo: use parent as self for subobjects drm/nv20-nv30/gr: use parent as self for subobjects drm/nvc0-/gr: use self as parent for subobjects drm/nv04-nv40/instmem: use self as parent for subobjects drm/nv04-nv40/vm: use self as parent for subobjects drm/nv50-/bar: use self as parent for subobjects drm/nv04-nv40/instmem: remove parent deref hack drm/nouveau/i2c: remove parent deref hack drm/nouveau/core: rebase object ref/use counts after ctor/init/fini events drm/nv50/disp: inform core when we're not creating a new context drm/nouveau/therm: send some messages to debug level drm/nve0/gr: add handling for a bunch of PGRAPH traps ...
This commit is contained in:
commit
36d9b1541c
|
@ -53,15 +53,6 @@ nouveau-y += core/subdev/clock/nva3.o
|
|||
nouveau-y += core/subdev/clock/nvc0.o
|
||||
nouveau-y += core/subdev/clock/pllnv04.o
|
||||
nouveau-y += core/subdev/clock/pllnva3.o
|
||||
nouveau-y += core/subdev/device/base.o
|
||||
nouveau-y += core/subdev/device/nv04.o
|
||||
nouveau-y += core/subdev/device/nv10.o
|
||||
nouveau-y += core/subdev/device/nv20.o
|
||||
nouveau-y += core/subdev/device/nv30.o
|
||||
nouveau-y += core/subdev/device/nv40.o
|
||||
nouveau-y += core/subdev/device/nv50.o
|
||||
nouveau-y += core/subdev/device/nvc0.o
|
||||
nouveau-y += core/subdev/device/nve0.o
|
||||
nouveau-y += core/subdev/devinit/base.o
|
||||
nouveau-y += core/subdev/devinit/nv04.o
|
||||
nouveau-y += core/subdev/devinit/nv05.o
|
||||
|
@ -126,6 +117,7 @@ nouveau-y += core/subdev/therm/ic.o
|
|||
nouveau-y += core/subdev/therm/temp.o
|
||||
nouveau-y += core/subdev/therm/nv40.o
|
||||
nouveau-y += core/subdev/therm/nv50.o
|
||||
nouveau-y += core/subdev/therm/nv84.o
|
||||
nouveau-y += core/subdev/therm/nva3.o
|
||||
nouveau-y += core/subdev/therm/nvd0.o
|
||||
nouveau-y += core/subdev/timer/base.o
|
||||
|
@ -150,6 +142,15 @@ 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/base.o
|
||||
nouveau-y += core/engine/device/nv04.o
|
||||
nouveau-y += core/engine/device/nv10.o
|
||||
nouveau-y += core/engine/device/nv20.o
|
||||
nouveau-y += core/engine/device/nv30.o
|
||||
nouveau-y += core/engine/device/nv40.o
|
||||
nouveau-y += core/engine/device/nv50.o
|
||||
nouveau-y += core/engine/device/nvc0.o
|
||||
nouveau-y += core/engine/device/nve0.o
|
||||
nouveau-y += core/engine/disp/base.o
|
||||
nouveau-y += core/engine/disp/nv04.o
|
||||
nouveau-y += core/engine/disp/nv50.o
|
||||
|
@ -212,7 +213,7 @@ nouveau-y += core/engine/vp/nve0.o
|
|||
|
||||
# drm/core
|
||||
nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
|
||||
nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.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 += nv04_fence.o nv10_fence.o nv17_fence.o
|
||||
|
@ -224,9 +225,7 @@ nouveau-y += nouveau_connector.o nouveau_dp.o
|
|||
nouveau-y += nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o
|
||||
|
||||
# drm/kms/nv04:nv50
|
||||
nouveau-y += nouveau_hw.o nouveau_calc.o
|
||||
nouveau-y += nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o
|
||||
nouveau-y += nv04_crtc.o nv04_display.o nv04_cursor.o
|
||||
include $(src)/dispnv04/Makefile
|
||||
|
||||
# drm/kms/nv50-
|
||||
nouveau-y += nv50_display.o
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <core/handle.h>
|
||||
#include <core/option.h>
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <engine/device.h>
|
||||
|
||||
static void
|
||||
nouveau_client_dtor(struct nouveau_object *object)
|
||||
|
@ -58,8 +58,9 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg,
|
|||
return -ENODEV;
|
||||
|
||||
ret = nouveau_namedb_create_(NULL, NULL, &nouveau_client_oclass,
|
||||
NV_CLIENT_CLASS, nouveau_device_sclass,
|
||||
0, length, pobject);
|
||||
NV_CLIENT_CLASS, NULL,
|
||||
(1ULL << NVDEV_ENGINE_DEVICE),
|
||||
length, pobject);
|
||||
client = *pobject;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -33,7 +33,6 @@ nouveau_engine_create_(struct nouveau_object *parent,
|
|||
const char *iname, const char *fname,
|
||||
int length, void **pobject)
|
||||
{
|
||||
struct nouveau_device *device = nv_device(parent);
|
||||
struct nouveau_engine *engine;
|
||||
int ret;
|
||||
|
||||
|
@ -43,7 +42,8 @@ nouveau_engine_create_(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!nouveau_boolopt(device->cfgopt, iname, enable)) {
|
||||
if ( parent &&
|
||||
!nouveau_boolopt(nv_device(parent)->cfgopt, iname, enable)) {
|
||||
if (!enable)
|
||||
nv_warn(engine, "disabled, %s=1 to enable\n", iname);
|
||||
return -ENODEV;
|
||||
|
|
|
@ -27,8 +27,10 @@ static void
|
|||
nouveau_event_put_locked(struct nouveau_event *event, int index,
|
||||
struct nouveau_eventh *handler)
|
||||
{
|
||||
if (!--event->index[index].refs)
|
||||
event->disable(event, index);
|
||||
if (!--event->index[index].refs) {
|
||||
if (event->disable)
|
||||
event->disable(event, index);
|
||||
}
|
||||
list_del(&handler->head);
|
||||
}
|
||||
|
||||
|
@ -53,8 +55,10 @@ nouveau_event_get(struct nouveau_event *event, int index,
|
|||
spin_lock_irqsave(&event->lock, flags);
|
||||
if (index < event->index_nr) {
|
||||
list_add(&handler->head, &event->index[index].list);
|
||||
if (!event->index[index].refs++)
|
||||
event->enable(event, index);
|
||||
if (!event->index[index].refs++) {
|
||||
if (event->enable)
|
||||
event->enable(event, index);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&event->lock, flags);
|
||||
}
|
||||
|
|
|
@ -136,26 +136,30 @@ nouveau_object_ctor(struct nouveau_object *parent,
|
|||
struct nouveau_object **pobject)
|
||||
{
|
||||
struct nouveau_ofuncs *ofuncs = oclass->ofuncs;
|
||||
struct nouveau_object *object = NULL;
|
||||
int ret;
|
||||
|
||||
*pobject = NULL;
|
||||
|
||||
ret = ofuncs->ctor(parent, engine, oclass, data, size, pobject);
|
||||
ret = ofuncs->ctor(parent, engine, oclass, data, size, &object);
|
||||
*pobject = object;
|
||||
if (ret < 0) {
|
||||
if (ret != -ENODEV) {
|
||||
nv_error(parent, "failed to create 0x%08x, %d\n",
|
||||
oclass->handle, ret);
|
||||
}
|
||||
|
||||
if (*pobject) {
|
||||
ofuncs->dtor(*pobject);
|
||||
if (object) {
|
||||
ofuncs->dtor(object);
|
||||
*pobject = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nv_debug(*pobject, "created\n");
|
||||
if (ret == 0) {
|
||||
nv_debug(object, "created\n");
|
||||
atomic_set(&object->refcount, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -327,6 +331,7 @@ nouveau_object_inc(struct nouveau_object *object)
|
|||
}
|
||||
|
||||
ret = nv_ofuncs(object)->init(object);
|
||||
atomic_set(&object->usecount, 1);
|
||||
if (ret) {
|
||||
nv_error(object, "init failed, %d\n", ret);
|
||||
goto fail_self;
|
||||
|
@ -357,6 +362,7 @@ nouveau_object_decf(struct nouveau_object *object)
|
|||
nv_trace(object, "stopping...\n");
|
||||
|
||||
ret = nv_ofuncs(object)->fini(object, false);
|
||||
atomic_set(&object->usecount, 0);
|
||||
if (ret)
|
||||
nv_warn(object, "failed fini, %d\n", ret);
|
||||
|
||||
|
@ -381,6 +387,7 @@ nouveau_object_decs(struct nouveau_object *object)
|
|||
nv_trace(object, "suspending...\n");
|
||||
|
||||
ret = nv_ofuncs(object)->fini(object, true);
|
||||
atomic_set(&object->usecount, 0);
|
||||
if (ret) {
|
||||
nv_error(object, "failed suspend, %d\n", ret);
|
||||
return ret;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <core/object.h>
|
||||
#include <core/parent.h>
|
||||
#include <core/client.h>
|
||||
|
||||
int
|
||||
nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
|
||||
|
@ -50,7 +51,12 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
|
|||
while (mask) {
|
||||
int i = ffsll(mask) - 1;
|
||||
|
||||
if ((engine = nouveau_engine(parent, i))) {
|
||||
if (nv_iclass(parent, NV_CLIENT_CLASS))
|
||||
engine = nv_engine(nv_client(parent)->device);
|
||||
else
|
||||
engine = nouveau_engine(parent, i);
|
||||
|
||||
if (engine) {
|
||||
oclass = engine->sclass;
|
||||
while (oclass->ofuncs) {
|
||||
if ((oclass->handle & 0xffff) == handle) {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include <core/class.h>
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <engine/device.h>
|
||||
|
||||
static DEFINE_MUTEX(nv_devices_mutex);
|
||||
static LIST_HEAD(nv_devices);
|
||||
|
@ -55,7 +55,6 @@ nouveau_device_find(u64 name)
|
|||
struct nouveau_devobj {
|
||||
struct nouveau_parent base;
|
||||
struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
|
||||
bool created;
|
||||
};
|
||||
|
||||
static const u64 disable_map[] = {
|
||||
|
@ -238,26 +237,24 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
|
|||
}
|
||||
|
||||
/* ensure requested subsystems are available for use */
|
||||
for (i = 0, c = 0; i < NVDEV_SUBDEV_NR; i++) {
|
||||
for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) {
|
||||
if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
|
||||
continue;
|
||||
|
||||
if (!device->subdev[i]) {
|
||||
ret = nouveau_object_ctor(nv_object(device), NULL,
|
||||
oclass, NULL, i,
|
||||
&devobj->subdev[i]);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (nv_iclass(devobj->subdev[i], NV_ENGINE_CLASS))
|
||||
nouveau_subdev_reset(devobj->subdev[i]);
|
||||
} else {
|
||||
if (device->subdev[i]) {
|
||||
nouveau_object_ref(device->subdev[i],
|
||||
&devobj->subdev[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = nouveau_object_ctor(nv_object(device), NULL,
|
||||
oclass, NULL, i,
|
||||
&devobj->subdev[i]);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* note: can't init *any* subdevs until devinit has been run
|
||||
* due to not knowing exactly what the vbios init tables will
|
||||
* mess with. devinit also can't be run until all of its
|
||||
|
@ -273,6 +270,10 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
|
|||
ret = nouveau_object_inc(subdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
atomic_dec(&nv_object(device)->usecount);
|
||||
} else
|
||||
if (subdev) {
|
||||
nouveau_subdev_reset(subdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,74 +293,6 @@ nouveau_devobj_dtor(struct nouveau_object *object)
|
|||
nouveau_parent_destroy(&devobj->base);
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_devobj_init(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_devobj *devobj = (void *)object;
|
||||
struct nouveau_object *subdev;
|
||||
int ret, i;
|
||||
|
||||
ret = nouveau_parent_init(&devobj->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; devobj->created && i < NVDEV_SUBDEV_NR; i++) {
|
||||
if ((subdev = devobj->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
|
||||
ret = nouveau_object_inc(subdev);
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devobj->created = true;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
for (--i; i >= 0; i--) {
|
||||
if ((subdev = devobj->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS))
|
||||
nouveau_object_dec(subdev, false);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_devobj_fini(struct nouveau_object *object, bool suspend)
|
||||
{
|
||||
struct nouveau_devobj *devobj = (void *)object;
|
||||
struct nouveau_object *subdev;
|
||||
int ret, i;
|
||||
|
||||
for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
|
||||
if ((subdev = devobj->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
|
||||
ret = nouveau_object_dec(subdev, suspend);
|
||||
if (ret && suspend)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = nouveau_parent_fini(&devobj->base, suspend);
|
||||
fail:
|
||||
for (; ret && suspend && i < NVDEV_SUBDEV_NR; i++) {
|
||||
if ((subdev = devobj->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
|
||||
ret = nouveau_object_inc(subdev);
|
||||
if (ret) {
|
||||
/* XXX */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8
|
||||
nouveau_devobj_rd08(struct nouveau_object *object, u64 addr)
|
||||
{
|
||||
|
@ -400,8 +333,8 @@ static struct nouveau_ofuncs
|
|||
nouveau_devobj_ofuncs = {
|
||||
.ctor = nouveau_devobj_ctor,
|
||||
.dtor = nouveau_devobj_dtor,
|
||||
.init = nouveau_devobj_init,
|
||||
.fini = nouveau_devobj_fini,
|
||||
.init = _nouveau_parent_init,
|
||||
.fini = _nouveau_parent_fini,
|
||||
.rd08 = nouveau_devobj_rd08,
|
||||
.rd16 = nouveau_devobj_rd16,
|
||||
.rd32 = nouveau_devobj_rd32,
|
||||
|
@ -413,12 +346,76 @@ nouveau_devobj_ofuncs = {
|
|||
/******************************************************************************
|
||||
* nouveau_device: engine functions
|
||||
*****************************************************************************/
|
||||
struct nouveau_oclass
|
||||
static struct nouveau_oclass
|
||||
nouveau_device_sclass[] = {
|
||||
{ 0x0080, &nouveau_devobj_ofuncs },
|
||||
{}
|
||||
};
|
||||
|
||||
static int
|
||||
nouveau_device_fini(struct nouveau_object *object, bool suspend)
|
||||
{
|
||||
struct nouveau_device *device = (void *)object;
|
||||
struct nouveau_object *subdev;
|
||||
int ret, i;
|
||||
|
||||
for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
|
||||
if ((subdev = device->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
|
||||
ret = nouveau_object_dec(subdev, suspend);
|
||||
if (ret && suspend)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
for (; ret && i < NVDEV_SUBDEV_NR; i++) {
|
||||
if ((subdev = device->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
|
||||
ret = nouveau_object_inc(subdev);
|
||||
if (ret) {
|
||||
/* XXX */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_device_init(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_device *device = (void *)object;
|
||||
struct nouveau_object *subdev;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
|
||||
if ((subdev = device->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
|
||||
ret = nouveau_object_inc(subdev);
|
||||
if (ret)
|
||||
goto fail;
|
||||
} else {
|
||||
nouveau_subdev_reset(subdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
fail:
|
||||
for (--i; ret && i >= 0; i--) {
|
||||
if ((subdev = device->subdev[i])) {
|
||||
if (!nv_iclass(subdev, NV_ENGINE_CLASS))
|
||||
nouveau_object_dec(subdev, false);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
nouveau_device_dtor(struct nouveau_object *object)
|
||||
{
|
||||
|
@ -428,17 +425,19 @@ nouveau_device_dtor(struct nouveau_object *object)
|
|||
list_del(&device->head);
|
||||
mutex_unlock(&nv_devices_mutex);
|
||||
|
||||
if (device->base.mmio)
|
||||
iounmap(device->base.mmio);
|
||||
if (nv_subdev(device)->mmio)
|
||||
iounmap(nv_subdev(device)->mmio);
|
||||
|
||||
nouveau_subdev_destroy(&device->base);
|
||||
nouveau_engine_destroy(&device->base);
|
||||
}
|
||||
|
||||
static struct nouveau_oclass
|
||||
nouveau_device_oclass = {
|
||||
.handle = NV_SUBDEV(DEVICE, 0x00),
|
||||
.handle = NV_ENGINE(DEVICE, 0x00),
|
||||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.dtor = nouveau_device_dtor,
|
||||
.init = nouveau_device_init,
|
||||
.fini = nouveau_device_fini,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -456,13 +455,12 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
|
|||
goto done;
|
||||
}
|
||||
|
||||
ret = nouveau_subdev_create_(NULL, NULL, &nouveau_device_oclass, 0,
|
||||
ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true,
|
||||
"DEVICE", "device", length, pobject);
|
||||
device = *pobject;
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
atomic_set(&nv_object(device)->usecount, 2);
|
||||
device->pdev = pdev;
|
||||
device->handle = name;
|
||||
device->cfgopt = cfg;
|
||||
|
@ -470,6 +468,7 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
|
|||
device->name = sname;
|
||||
|
||||
nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
|
||||
nv_engine(device)->sclass = nouveau_device_sclass;
|
||||
list_add(&device->head, &nv_devices);
|
||||
done:
|
||||
mutex_unlock(&nv_devices_mutex);
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/i2c.h>
|
||||
|
@ -34,6 +33,7 @@
|
|||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/gpio.h>
|
||||
|
@ -35,6 +34,7 @@
|
|||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/gpio.h>
|
||||
|
@ -36,6 +35,7 @@
|
|||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/gpio.h>
|
||||
|
@ -35,6 +34,7 @@
|
|||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/vm.h>
|
||||
|
@ -37,6 +36,7 @@
|
|||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/gpio.h>
|
||||
|
@ -38,6 +37,7 @@
|
|||
#include <subdev/vm.h>
|
||||
#include <subdev/bar.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
||||
|
@ -83,7 +83,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
|
||||
|
@ -109,7 +109,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
|
||||
|
@ -135,7 +135,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
|
||||
|
@ -161,7 +161,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
|
||||
|
@ -187,7 +187,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
|
||||
|
@ -213,7 +213,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
|
||||
|
@ -239,7 +239,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
|
||||
|
@ -265,7 +265,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
|
||||
|
@ -291,7 +291,7 @@ nv50_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/gpio.h>
|
||||
|
@ -40,6 +39,7 @@
|
|||
#include <subdev/vm.h>
|
||||
#include <subdev/bar.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
||||
|
@ -285,6 +285,34 @@ nvc0_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
|
||||
break;
|
||||
case 0xd7:
|
||||
device->cname = "GF117";
|
||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
|
||||
device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
|
||||
device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
|
||||
break;
|
||||
default:
|
||||
nv_fatal(device, "unknown Fermi chipset\n");
|
||||
return -EINVAL;
|
|
@ -22,7 +22,6 @@
|
|||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bus.h>
|
||||
#include <subdev/gpio.h>
|
||||
|
@ -40,6 +39,7 @@
|
|||
#include <subdev/vm.h>
|
||||
#include <subdev/bar.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
#include <engine/fifo.h>
|
||||
#include <engine/software.h>
|
|
@ -191,7 +191,7 @@ dp_link_train_cr(struct dp_state *dp)
|
|||
static int
|
||||
dp_link_train_eq(struct dp_state *dp)
|
||||
{
|
||||
bool eq_done, cr_done = true;
|
||||
bool eq_done = false, cr_done = true;
|
||||
int tries = 0, i;
|
||||
|
||||
dp_set_training_pattern(dp, 2);
|
||||
|
|
|
@ -572,7 +572,8 @@ nv50_disp_base_ctor(struct nouveau_object *parent,
|
|||
priv->base.vblank->priv = priv;
|
||||
priv->base.vblank->enable = nv50_disp_base_vblank_enable;
|
||||
priv->base.vblank->disable = nv50_disp_base_vblank_disable;
|
||||
return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht);
|
||||
return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
|
||||
&base->ramht);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -719,7 +720,7 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
|
|||
if (nv_mclass(parent) != NV_DEVICE_CLASS) {
|
||||
atomic_inc(&parent->refcount);
|
||||
*pobject = parent;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* allocate display hardware to client */
|
||||
|
|
|
@ -473,7 +473,8 @@ nvd0_disp_base_ctor(struct nouveau_object *parent,
|
|||
priv->base.vblank->enable = nvd0_disp_base_vblank_enable;
|
||||
priv->base.vblank->disable = nvd0_disp_base_vblank_disable;
|
||||
|
||||
return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht);
|
||||
return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
|
||||
&base->ramht);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -91,6 +91,8 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
|
|||
if (!chan->user)
|
||||
return -EFAULT;
|
||||
|
||||
nouveau_event_trigger(priv->cevent, 0);
|
||||
|
||||
chan->size = size;
|
||||
return 0;
|
||||
}
|
||||
|
@ -167,6 +169,7 @@ nouveau_fifo_destroy(struct nouveau_fifo *priv)
|
|||
{
|
||||
kfree(priv->channel);
|
||||
nouveau_event_destroy(&priv->uevent);
|
||||
nouveau_event_destroy(&priv->cevent);
|
||||
nouveau_engine_destroy(&priv->base);
|
||||
}
|
||||
|
||||
|
@ -191,6 +194,10 @@ nouveau_fifo_create_(struct nouveau_object *parent,
|
|||
if (!priv->channel)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nouveau_event_create(1, &priv->cevent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_event_create(1, &priv->uevent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -210,7 +210,8 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
|
|||
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
|
||||
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
|
||||
|
||||
ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
|
||||
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
|
||||
&chan->ramht);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -263,7 +264,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
|
|||
nv_parent(chan)->object_attach = nv50_fifo_object_attach;
|
||||
nv_parent(chan)->object_detach = nv50_fifo_object_detach;
|
||||
|
||||
ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
|
||||
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
|
||||
&chan->ramht);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -373,17 +375,17 @@ nv50_fifo_context_ctor(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0200, 0x1000,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200,
|
||||
0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x1200, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1200, 0,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x4000, 0, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0, 0,
|
||||
&base->pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -437,12 +439,12 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
|
||||
&priv->playlist[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
|
||||
&priv->playlist[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -180,7 +180,8 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
|
||||
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
|
||||
&chan->ramht);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -242,7 +243,8 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht);
|
||||
ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
|
||||
&chan->ramht);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -336,12 +338,12 @@ nv84_fifo_context_ctor(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0200, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200, 0,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x4000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0,
|
||||
0, &base->pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -350,13 +352,13 @@ nv84_fifo_context_ctor(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x1000, 0x400,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1000,
|
||||
0x400, NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0100, 0x100,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
|
||||
ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0100,
|
||||
0x100, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -407,12 +409,12 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
|
||||
&priv->playlist[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
|
||||
&priv->playlist[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -292,7 +292,8 @@ nvc0_fifo_context_ctor(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0x1000, 0, &base->pgd);
|
||||
ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
|
||||
&base->pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -623,17 +624,17 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
|
||||
&priv->playlist[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
|
||||
&priv->playlist[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 128 * 0x1000, 0x1000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0,
|
||||
&priv->user.mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -96,7 +96,7 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
|
|||
|
||||
cur = engn->playlist[engn->cur_playlist];
|
||||
if (unlikely(cur == NULL)) {
|
||||
int ret = nouveau_gpuobj_new(nv_object(priv)->parent, NULL,
|
||||
int ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
0x8000, 0x1000, 0, &cur);
|
||||
if (ret) {
|
||||
nv_error(priv, "playlist alloc failed\n");
|
||||
|
@ -333,7 +333,8 @@ nve0_fifo_context_ctor(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0x1000, 0, &base->pgd);
|
||||
ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
|
||||
&base->pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -595,7 +596,7 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 4096 * 0x200, 0x1000,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -36,7 +36,6 @@ int
|
|||
nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
|
||||
{
|
||||
struct nouveau_bar *bar = nouveau_bar(priv);
|
||||
struct nouveau_object *parent = nv_object(priv);
|
||||
struct nouveau_gpuobj *chan;
|
||||
u32 size = (0x80000 + priv->size + 4095) & ~4095;
|
||||
int ret, i;
|
||||
|
@ -44,7 +43,7 @@ nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
|
|||
/* allocate memory to for a "channel", which we'll use to generate
|
||||
* the default context values
|
||||
*/
|
||||
ret = nouveau_gpuobj_new(parent, NULL, size, 0x1000,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, size, 0x1000,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &info->chan);
|
||||
chan = info->chan;
|
||||
if (ret) {
|
||||
|
@ -1399,7 +1398,7 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) {
|
||||
for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
|
||||
nv_mthd(priv, 0x90c0, 0x2700 + (i * 0x40), 0x00000000);
|
||||
nv_mthd(priv, 0x90c0, 0x2720 + (i * 0x40), 0x00000000);
|
||||
nv_mthd(priv, 0x90c0, 0x2704 + (i * 0x40), 0x00000000);
|
||||
|
@ -1415,7 +1414,7 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
|
|||
nv_mthd(priv, 0x90c0, 0x27ac, 0x00000000);
|
||||
nv_mthd(priv, 0x90c0, 0x27cc, 0x00000000);
|
||||
nv_mthd(priv, 0x90c0, 0x27ec, 0x00000000);
|
||||
for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) {
|
||||
for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
|
||||
nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000);
|
||||
nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000);
|
||||
nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040);
|
||||
|
@ -1615,7 +1614,7 @@ static void
|
|||
nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv)
|
||||
{
|
||||
|
||||
if (nv_device(priv)->chipset == 0xd9) {
|
||||
if (nv_device(priv)->chipset >= 0xd0) {
|
||||
nv_wr32(priv, 0x405800, 0x0f8000bf);
|
||||
nv_wr32(priv, 0x405830, 0x02180218);
|
||||
nv_wr32(priv, 0x405834, 0x08000000);
|
||||
|
@ -1658,10 +1657,10 @@ nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x4064ac, 0x00003fff);
|
||||
nv_wr32(priv, 0x4064b4, 0x00000000);
|
||||
nv_wr32(priv, 0x4064b8, 0x00000000);
|
||||
if (nv_device(priv)->chipset == 0xd9)
|
||||
if (nv_device(priv)->chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x4064bc, 0x00000000);
|
||||
if (nv_device(priv)->chipset == 0xc1 ||
|
||||
nv_device(priv)->chipset == 0xd9) {
|
||||
nv_device(priv)->chipset >= 0xd0) {
|
||||
nv_wr32(priv, 0x4064c0, 0x80140078);
|
||||
nv_wr32(priv, 0x4064c4, 0x0086ffff);
|
||||
}
|
||||
|
@ -1701,7 +1700,7 @@ nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv)
|
|||
/* ROPC_BROADCAST */
|
||||
nv_wr32(priv, 0x408800, 0x02802a3c);
|
||||
nv_wr32(priv, 0x408804, 0x00000040);
|
||||
if (chipset == 0xd9) {
|
||||
if (chipset >= 0xd0) {
|
||||
nv_wr32(priv, 0x408808, 0x1043e005);
|
||||
nv_wr32(priv, 0x408900, 0x3080b801);
|
||||
nv_wr32(priv, 0x408904, 0x1043e005);
|
||||
|
@ -1735,7 +1734,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x418408, 0x00000000);
|
||||
nv_wr32(priv, 0x41840c, 0x00001008);
|
||||
nv_wr32(priv, 0x418410, 0x0fff0fff);
|
||||
nv_wr32(priv, 0x418414, chipset != 0xd9 ? 0x00200fff : 0x02200fff);
|
||||
nv_wr32(priv, 0x418414, chipset < 0xd0 ? 0x00200fff : 0x02200fff);
|
||||
nv_wr32(priv, 0x418450, 0x00000000);
|
||||
nv_wr32(priv, 0x418454, 0x00000000);
|
||||
nv_wr32(priv, 0x418458, 0x00000000);
|
||||
|
@ -1750,14 +1749,14 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x418700, 0x00000002);
|
||||
nv_wr32(priv, 0x418704, 0x00000080);
|
||||
nv_wr32(priv, 0x418708, 0x00000000);
|
||||
nv_wr32(priv, 0x41870c, chipset != 0xd9 ? 0x07c80000 : 0x00000000);
|
||||
nv_wr32(priv, 0x41870c, chipset < 0xd0 ? 0x07c80000 : 0x00000000);
|
||||
nv_wr32(priv, 0x418710, 0x00000000);
|
||||
nv_wr32(priv, 0x418800, chipset != 0xd9 ? 0x0006860a : 0x7006860a);
|
||||
nv_wr32(priv, 0x418800, chipset < 0xd0 ? 0x0006860a : 0x7006860a);
|
||||
nv_wr32(priv, 0x418808, 0x00000000);
|
||||
nv_wr32(priv, 0x41880c, 0x00000000);
|
||||
nv_wr32(priv, 0x418810, 0x00000000);
|
||||
nv_wr32(priv, 0x418828, 0x00008442);
|
||||
if (chipset == 0xc1 || chipset == 0xd9)
|
||||
if (chipset == 0xc1 || chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x418830, 0x10000001);
|
||||
else
|
||||
nv_wr32(priv, 0x418830, 0x00000001);
|
||||
|
@ -1768,7 +1767,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x4188f0, 0x00000000);
|
||||
nv_wr32(priv, 0x4188f4, 0x00000000);
|
||||
nv_wr32(priv, 0x4188f8, 0x00000000);
|
||||
if (chipset == 0xd9)
|
||||
if (chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x4188fc, 0x20100008);
|
||||
else if (chipset == 0xc1)
|
||||
nv_wr32(priv, 0x4188fc, 0x00100018);
|
||||
|
@ -1787,7 +1786,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000);
|
||||
nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000);
|
||||
}
|
||||
nv_wr32(priv, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006);
|
||||
nv_wr32(priv, 0x418b00, chipset < 0xd0 ? 0x00000000 : 0x00000006);
|
||||
nv_wr32(priv, 0x418b08, 0x0a418820);
|
||||
nv_wr32(priv, 0x418b0c, 0x062080e6);
|
||||
nv_wr32(priv, 0x418b10, 0x020398a4);
|
||||
|
@ -1804,7 +1803,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x418c24, 0x00000000);
|
||||
nv_wr32(priv, 0x418c28, 0x00000000);
|
||||
nv_wr32(priv, 0x418c2c, 0x00000000);
|
||||
if (chipset == 0xc1 || chipset == 0xd9)
|
||||
if (chipset == 0xc1 || chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x418c6c, 0x00000001);
|
||||
nv_wr32(priv, 0x418c80, 0x20200004);
|
||||
nv_wr32(priv, 0x418c8c, 0x00000001);
|
||||
|
@ -1823,7 +1822,7 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x419818, 0x00000000);
|
||||
nv_wr32(priv, 0x41983c, 0x00038bc7);
|
||||
nv_wr32(priv, 0x419848, 0x00000000);
|
||||
if (chipset == 0xc1 || chipset == 0xd9)
|
||||
if (chipset == 0xc1 || chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x419864, 0x00000129);
|
||||
else
|
||||
nv_wr32(priv, 0x419864, 0x0000012a);
|
||||
|
@ -1836,7 +1835,7 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x419a14, 0x00000200);
|
||||
nv_wr32(priv, 0x419a1c, 0x00000000);
|
||||
nv_wr32(priv, 0x419a20, 0x00000800);
|
||||
if (chipset == 0xd9)
|
||||
if (chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x00419ac4, 0x0017f440);
|
||||
else if (chipset != 0xc0 && chipset != 0xc8)
|
||||
nv_wr32(priv, 0x00419ac4, 0x0007f440);
|
||||
|
@ -1847,16 +1846,16 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x419b10, 0x0a418820);
|
||||
nv_wr32(priv, 0x419b14, 0x000000e6);
|
||||
nv_wr32(priv, 0x419bd0, 0x00900103);
|
||||
if (chipset == 0xc1 || chipset == 0xd9)
|
||||
if (chipset == 0xc1 || chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x419be0, 0x00400001);
|
||||
else
|
||||
nv_wr32(priv, 0x419be0, 0x00000001);
|
||||
nv_wr32(priv, 0x419be4, 0x00000000);
|
||||
nv_wr32(priv, 0x419c00, chipset != 0xd9 ? 0x00000002 : 0x0000000a);
|
||||
nv_wr32(priv, 0x419c00, chipset < 0xd0 ? 0x00000002 : 0x0000000a);
|
||||
nv_wr32(priv, 0x419c04, 0x00000006);
|
||||
nv_wr32(priv, 0x419c08, 0x00000002);
|
||||
nv_wr32(priv, 0x419c20, 0x00000000);
|
||||
if (nv_device(priv)->chipset == 0xd9) {
|
||||
if (nv_device(priv)->chipset >= 0xd0) {
|
||||
nv_wr32(priv, 0x419c24, 0x00084210);
|
||||
nv_wr32(priv, 0x419c28, 0x3cf3cf3c);
|
||||
nv_wr32(priv, 0x419cb0, 0x00020048);
|
||||
|
@ -1868,12 +1867,12 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
|
|||
}
|
||||
nv_wr32(priv, 0x419ce8, 0x00000000);
|
||||
nv_wr32(priv, 0x419cf4, 0x00000183);
|
||||
if (chipset == 0xc1 || chipset == 0xd9)
|
||||
if (chipset == 0xc1 || chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x419d20, 0x12180000);
|
||||
else
|
||||
nv_wr32(priv, 0x419d20, 0x02180000);
|
||||
nv_wr32(priv, 0x419d24, 0x00001fff);
|
||||
if (chipset == 0xc1 || chipset == 0xd9)
|
||||
if (chipset == 0xc1 || chipset >= 0xd0)
|
||||
nv_wr32(priv, 0x419d44, 0x02180218);
|
||||
nv_wr32(priv, 0x419e04, 0x00000000);
|
||||
nv_wr32(priv, 0x419e08, 0x00000000);
|
||||
|
@ -2210,7 +2209,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
|
|||
nv_icmd(priv, 0x00000215, 0x00000040);
|
||||
nv_icmd(priv, 0x00000216, 0x00000040);
|
||||
nv_icmd(priv, 0x00000217, 0x00000040);
|
||||
if (nv_device(priv)->chipset == 0xd9) {
|
||||
if (nv_device(priv)->chipset >= 0xd0) {
|
||||
for (i = 0x0400; i <= 0x0417; i++)
|
||||
nv_icmd(priv, i, 0x00000040);
|
||||
}
|
||||
|
@ -2222,7 +2221,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
|
|||
nv_icmd(priv, 0x0000021d, 0x0000c080);
|
||||
nv_icmd(priv, 0x0000021e, 0x0000c080);
|
||||
nv_icmd(priv, 0x0000021f, 0x0000c080);
|
||||
if (nv_device(priv)->chipset == 0xd9) {
|
||||
if (nv_device(priv)->chipset >= 0xd0) {
|
||||
for (i = 0x0440; i <= 0x0457; i++)
|
||||
nv_icmd(priv, i, 0x0000c080);
|
||||
}
|
||||
|
@ -2789,7 +2788,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
|
|||
nv_icmd(priv, 0x00000585, 0x0000003f);
|
||||
nv_icmd(priv, 0x00000576, 0x00000003);
|
||||
if (nv_device(priv)->chipset == 0xc1 ||
|
||||
nv_device(priv)->chipset == 0xd9)
|
||||
nv_device(priv)->chipset >= 0xd0)
|
||||
nv_icmd(priv, 0x0000057b, 0x00000059);
|
||||
nv_icmd(priv, 0x00000586, 0x00000040);
|
||||
nv_icmd(priv, 0x00000582, 0x00000080);
|
||||
|
@ -2891,7 +2890,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
|
|||
nv_icmd(priv, 0x00000957, 0x00000003);
|
||||
nv_icmd(priv, 0x0000095e, 0x20164010);
|
||||
nv_icmd(priv, 0x0000095f, 0x00000020);
|
||||
if (nv_device(priv)->chipset == 0xd9)
|
||||
if (nv_device(priv)->chipset >= 0xd0)
|
||||
nv_icmd(priv, 0x0000097d, 0x00000020);
|
||||
nv_icmd(priv, 0x00000683, 0x00000006);
|
||||
nv_icmd(priv, 0x00000685, 0x003fffff);
|
||||
|
|
|
@ -2772,10 +2772,15 @@ nve0_grctx_generate(struct nvc0_graph_priv *priv)
|
|||
for (i = 0; i < 8; i++)
|
||||
nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
|
||||
|
||||
nv_wr32(priv, 0x405b00, 0x201);
|
||||
nv_wr32(priv, 0x408850, 0x2);
|
||||
nv_wr32(priv, 0x408958, 0x2);
|
||||
nv_wr32(priv, 0x419f78, 0xa);
|
||||
nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr);
|
||||
if (priv->gpc_nr == 1) {
|
||||
nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]);
|
||||
nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]);
|
||||
} else {
|
||||
nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr);
|
||||
nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
|
||||
}
|
||||
nv_mask(priv, 0x419f78, 0x00000001, 0x00000000);
|
||||
|
||||
nve0_grctx_generate_icmd(priv);
|
||||
nve0_grctx_generate_a097(priv);
|
||||
|
|
|
@ -87,6 +87,11 @@ chipsets:
|
|||
.b16 #nvd9_gpc_mmio_tail
|
||||
.b16 #nvd9_tpc_mmio_head
|
||||
.b16 #nvd9_tpc_mmio_tail
|
||||
.b8 0xd7 0 0 0
|
||||
.b16 #nvd9_gpc_mmio_head
|
||||
.b16 #nvd9_gpc_mmio_tail
|
||||
.b16 #nvd9_tpc_mmio_head
|
||||
.b16 #nvd9_tpc_mmio_tail
|
||||
.b8 0 0 0 0
|
||||
|
||||
// GPC mmio lists
|
||||
|
|
|
@ -62,6 +62,9 @@ chipsets:
|
|||
.b8 0xd9 0 0 0
|
||||
.b16 #nvd9_hub_mmio_head
|
||||
.b16 #nvd9_hub_mmio_tail
|
||||
.b8 0xd7 0 0 0
|
||||
.b16 #nvd9_hub_mmio_head
|
||||
.b16 #nvd9_hub_mmio_tail
|
||||
.b8 0 0 0 0
|
||||
|
||||
nvc0_hub_mmio_head:
|
||||
|
|
|
@ -254,7 +254,7 @@ nv20_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -142,7 +142,7 @@ nv25_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -109,7 +109,7 @@ nv2a_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -143,7 +143,7 @@ nv30_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -143,7 +143,7 @@ nv34_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -141,7 +141,7 @@ nv35_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -46,6 +46,14 @@ struct nv40_graph_chan {
|
|||
struct nouveau_graph_chan base;
|
||||
};
|
||||
|
||||
static u64
|
||||
nv40_graph_units(struct nouveau_graph *graph)
|
||||
{
|
||||
struct nv40_graph_priv *priv = (void *)graph;
|
||||
|
||||
return nv_rd32(priv, 0x1540);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Graphics object classes
|
||||
******************************************************************************/
|
||||
|
@ -359,6 +367,8 @@ nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
else
|
||||
nv_engine(priv)->sclass = nv40_graph_sclass;
|
||||
nv_engine(priv)->tile_prog = nv40_graph_tile_prog;
|
||||
|
||||
priv->base.units = nv40_graph_units;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,14 @@ struct nv50_graph_chan {
|
|||
struct nouveau_graph_chan base;
|
||||
};
|
||||
|
||||
static u64
|
||||
nv50_graph_units(struct nouveau_graph *graph)
|
||||
{
|
||||
struct nv50_graph_priv *priv = (void *)graph;
|
||||
|
||||
return nv_rd32(priv, 0x1540);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Graphics object classes
|
||||
******************************************************************************/
|
||||
|
@ -819,6 +827,8 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
nv_subdev(priv)->intr = nv50_graph_intr;
|
||||
nv_engine(priv)->cclass = &nv50_graph_cclass;
|
||||
|
||||
priv->base.units = nv50_graph_units;
|
||||
|
||||
switch (nv_device(priv)->chipset) {
|
||||
case 0x50:
|
||||
nv_engine(priv)->sclass = nv50_graph_sclass;
|
||||
|
|
|
@ -60,6 +60,19 @@ nvc8_graph_sclass[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
u64
|
||||
nvc0_graph_units(struct nouveau_graph *graph)
|
||||
{
|
||||
struct nvc0_graph_priv *priv = (void *)graph;
|
||||
u64 cfg;
|
||||
|
||||
cfg = (u32)priv->gpc_nr;
|
||||
cfg |= (u32)priv->tpc_total << 8;
|
||||
cfg |= (u64)priv->rop_nr << 32;
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* PGRAPH context
|
||||
******************************************************************************/
|
||||
|
@ -89,7 +102,8 @@ nvc0_graph_context_ctor(struct nouveau_object *parent,
|
|||
* fuc to modify some per-context register settings on first load
|
||||
* of the context.
|
||||
*/
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x100, 0, &chan->mmio);
|
||||
ret = nouveau_gpuobj_new(nv_object(chan), NULL, 0x1000, 0x100, 0,
|
||||
&chan->mmio);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -101,8 +115,8 @@ nvc0_graph_context_ctor(struct nouveau_object *parent,
|
|||
|
||||
/* allocate buffers referenced by mmio list */
|
||||
for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) {
|
||||
ret = nouveau_gpuobj_new(parent, NULL, data->size, data->align,
|
||||
0, &chan->data[i].mem);
|
||||
ret = nouveau_gpuobj_new(nv_object(chan), NULL, data->size,
|
||||
data->align, 0, &chan->data[i].mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -518,9 +532,10 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
{
|
||||
struct nouveau_device *device = nv_device(parent);
|
||||
struct nvc0_graph_priv *priv;
|
||||
bool enable = device->chipset != 0xd7;
|
||||
int ret, i;
|
||||
|
||||
ret = nouveau_graph_create(parent, engine, oclass, true, &priv);
|
||||
ret = nouveau_graph_create(parent, engine, oclass, enable, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -529,6 +544,8 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
nv_subdev(priv)->intr = nvc0_graph_intr;
|
||||
nv_engine(priv)->cclass = &nvc0_graph_cclass;
|
||||
|
||||
priv->base.units = nvc0_graph_units;
|
||||
|
||||
if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
|
||||
nv_info(priv, "using external firmware\n");
|
||||
if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
|
||||
|
@ -551,11 +568,13 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
break;
|
||||
}
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
|
||||
&priv->unk4188b4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
|
||||
&priv->unk4188b8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ nvc0_graph_class(void *obj)
|
|||
return 0x9197;
|
||||
case 0xc8:
|
||||
case 0xd9:
|
||||
case 0xd7:
|
||||
return 0x9297;
|
||||
case 0xe4:
|
||||
case 0xe7:
|
||||
|
@ -169,4 +170,6 @@ int nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
|
|||
struct nouveau_object **);
|
||||
void nvc0_graph_context_dtor(struct nouveau_object *);
|
||||
|
||||
u64 nvc0_graph_units(struct nouveau_graph *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -77,11 +77,207 @@ nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
|
|||
nv_wr32(priv, 0x409c20, ustat);
|
||||
}
|
||||
|
||||
static const struct nouveau_enum nve0_mp_warp_error[] = {
|
||||
{ 0x00, "NO_ERROR" },
|
||||
{ 0x01, "STACK_MISMATCH" },
|
||||
{ 0x05, "MISALIGNED_PC" },
|
||||
{ 0x08, "MISALIGNED_GPR" },
|
||||
{ 0x09, "INVALID_OPCODE" },
|
||||
{ 0x0d, "GPR_OUT_OF_BOUNDS" },
|
||||
{ 0x0e, "MEM_OUT_OF_BOUNDS" },
|
||||
{ 0x0f, "UNALIGNED_MEM_ACCESS" },
|
||||
{ 0x11, "INVALID_PARAM" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nouveau_enum nve0_mp_global_error[] = {
|
||||
{ 2, "MULTIPLE_WARP_ERRORS" },
|
||||
{ 3, "OUT_OF_STACK_SPACE" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nouveau_enum nve0_gpc_rop_error[] = {
|
||||
{ 1, "RT_PITCH_OVERRUN" },
|
||||
{ 4, "RT_WIDTH_OVERRUN" },
|
||||
{ 5, "RT_HEIGHT_OVERRUN" },
|
||||
{ 7, "ZETA_STORAGE_TYPE_MISMATCH" },
|
||||
{ 8, "RT_STORAGE_TYPE_MISMATCH" },
|
||||
{ 10, "RT_LINEAR_MISMATCH" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nouveau_enum nve0_sked_error[] = {
|
||||
{ 7, "CONSTANT_BUFFER_SIZE" },
|
||||
{ 9, "LOCAL_MEMORY_SIZE_POS" },
|
||||
{ 10, "LOCAL_MEMORY_SIZE_NEG" },
|
||||
{ 11, "WARP_CSTACK_SIZE" },
|
||||
{ 12, "TOTAL_TEMP_SIZE" },
|
||||
{ 13, "REGISTER_COUNT" },
|
||||
{ 18, "TOTAL_THREADS" },
|
||||
{ 20, "PROGRAM_OFFSET" },
|
||||
{ 21, "SHARED_MEMORY_SIZE" },
|
||||
{ 25, "SHARED_CONFIG_TOO_SMALL" },
|
||||
{ 26, "TOTAL_REGISTER_COUNT" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
nve0_graph_mp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
|
||||
{
|
||||
int i;
|
||||
u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x648));
|
||||
u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x650));
|
||||
|
||||
nv_error(priv, "GPC%i/TP%i/MP trap:", gpc, tp);
|
||||
|
||||
for (i = 0; i <= 31; ++i) {
|
||||
if (!(gerr & (1 << i)))
|
||||
continue;
|
||||
pr_cont(" ");
|
||||
nouveau_enum_print(nve0_mp_global_error, i);
|
||||
}
|
||||
if (werr) {
|
||||
pr_cont(" ");
|
||||
nouveau_enum_print(nve0_mp_warp_error, werr & 0xffff);
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
/* disable MP trap to avoid spam */
|
||||
nv_mask(priv, TPC_UNIT(gpc, tp, 0x50c), 0x2, 0x0);
|
||||
|
||||
/* TODO: figure out how to resume after an MP trap */
|
||||
}
|
||||
|
||||
static void
|
||||
nve0_graph_tp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
|
||||
{
|
||||
u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x508));
|
||||
|
||||
if (stat & 0x1) {
|
||||
u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x224));
|
||||
nv_error(priv, "GPC%i/TP%i/TEX trap: %08x\n",
|
||||
gpc, tp, trap);
|
||||
|
||||
nv_wr32(priv, TPC_UNIT(gpc, tp, 0x224), 0xc0000000);
|
||||
stat &= ~0x1;
|
||||
}
|
||||
|
||||
if (stat & 0x2) {
|
||||
nve0_graph_mp_trap(priv, gpc, tp);
|
||||
stat &= ~0x2;
|
||||
}
|
||||
|
||||
if (stat & 0x4) {
|
||||
u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x084));
|
||||
nv_error(priv, "GPC%i/TP%i/POLY trap: %08x\n",
|
||||
gpc, tp, trap);
|
||||
|
||||
nv_wr32(priv, TPC_UNIT(gpc, tp, 0x084), 0xc0000000);
|
||||
stat &= ~0x4;
|
||||
}
|
||||
|
||||
if (stat & 0x8) {
|
||||
u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x48c));
|
||||
nv_error(priv, "GPC%i/TP%i/L1C trap: %08x\n",
|
||||
gpc, tp, trap);
|
||||
|
||||
nv_wr32(priv, TPC_UNIT(gpc, tp, 0x48c), 0xc0000000);
|
||||
stat &= ~0x8;
|
||||
}
|
||||
|
||||
if (stat) {
|
||||
nv_error(priv, "GPC%i/TP%i: unknown stat %08x\n",
|
||||
gpc, tp, stat);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nve0_graph_gpc_trap(struct nvc0_graph_priv *priv)
|
||||
{
|
||||
const u32 mask = nv_rd32(priv, 0x400118);
|
||||
int gpc;
|
||||
|
||||
for (gpc = 0; gpc < 4; ++gpc) {
|
||||
u32 stat;
|
||||
int tp;
|
||||
|
||||
if (!(mask & (1 << gpc)))
|
||||
continue;
|
||||
stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90));
|
||||
|
||||
if (stat & 0x0001) {
|
||||
u32 trap[4];
|
||||
int i;
|
||||
|
||||
trap[0] = nv_rd32(priv, GPC_UNIT(gpc, 0x0420));
|
||||
trap[1] = nv_rd32(priv, GPC_UNIT(gpc, 0x0434));
|
||||
trap[2] = nv_rd32(priv, GPC_UNIT(gpc, 0x0438));
|
||||
trap[3] = nv_rd32(priv, GPC_UNIT(gpc, 0x043c));
|
||||
|
||||
nv_error(priv, "GPC%i/PROP trap:", gpc);
|
||||
for (i = 0; i <= 29; ++i) {
|
||||
if (!(trap[0] & (1 << i)))
|
||||
continue;
|
||||
pr_cont(" ");
|
||||
nouveau_enum_print(nve0_gpc_rop_error, i);
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
nv_error(priv, "x = %u, y = %u, "
|
||||
"format = %x, storage type = %x\n",
|
||||
trap[1] & 0xffff,
|
||||
trap[1] >> 16,
|
||||
(trap[2] >> 8) & 0x3f,
|
||||
trap[3] & 0xff);
|
||||
|
||||
nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
|
||||
stat &= ~0x0001;
|
||||
}
|
||||
|
||||
if (stat & 0x0002) {
|
||||
u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900));
|
||||
nv_error(priv, "GPC%i/ZCULL trap: %08x\n", gpc,
|
||||
trap);
|
||||
nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
|
||||
stat &= ~0x0002;
|
||||
}
|
||||
|
||||
if (stat & 0x0004) {
|
||||
u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028));
|
||||
nv_error(priv, "GPC%i/CCACHE trap: %08x\n", gpc,
|
||||
trap);
|
||||
nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
|
||||
stat &= ~0x0004;
|
||||
}
|
||||
|
||||
if (stat & 0x0008) {
|
||||
u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824));
|
||||
nv_error(priv, "GPC%i/ESETUP trap %08x\n", gpc,
|
||||
trap);
|
||||
nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
|
||||
stat &= ~0x0008;
|
||||
}
|
||||
|
||||
for (tp = 0; tp < 8; ++tp) {
|
||||
if (stat & (1 << (16 + tp)))
|
||||
nve0_graph_tp_trap(priv, gpc, tp);
|
||||
}
|
||||
stat &= ~0xff0000;
|
||||
|
||||
if (stat) {
|
||||
nv_error(priv, "GPC%i: unknown stat %08x\n",
|
||||
gpc, stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst,
|
||||
struct nouveau_object *engctx)
|
||||
{
|
||||
u32 trap = nv_rd32(priv, 0x400108);
|
||||
int i;
|
||||
int rop;
|
||||
|
||||
if (trap & 0x00000001) {
|
||||
|
@ -102,6 +298,32 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst,
|
|||
trap &= ~0x00000010;
|
||||
}
|
||||
|
||||
if (trap & 0x00000100) {
|
||||
u32 stat = nv_rd32(priv, 0x407020);
|
||||
nv_error(priv, "SKED ch %d [0x%010llx %s]:",
|
||||
chid, inst, nouveau_client_name(engctx));
|
||||
|
||||
for (i = 0; i <= 29; ++i) {
|
||||
if (!(stat & (1 << i)))
|
||||
continue;
|
||||
pr_cont(" ");
|
||||
nouveau_enum_print(nve0_sked_error, i);
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
if (stat & 0x3fffffff)
|
||||
nv_wr32(priv, 0x407020, 0x40000000);
|
||||
nv_wr32(priv, 0x400108, 0x00000100);
|
||||
trap &= ~0x00000100;
|
||||
}
|
||||
|
||||
if (trap & 0x01000000) {
|
||||
nv_error(priv, "GPC ch %d [0x%010llx %s]:\n",
|
||||
chid, inst, nouveau_client_name(engctx));
|
||||
nve0_graph_gpc_trap(priv);
|
||||
trap &= ~0x01000000;
|
||||
}
|
||||
|
||||
if (trap & 0x02000000) {
|
||||
for (rop = 0; rop < priv->rop_nr; rop++) {
|
||||
u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070));
|
||||
|
@ -217,6 +439,8 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
nv_engine(priv)->cclass = &nve0_graph_cclass;
|
||||
nv_engine(priv)->sclass = nve0_graph_sclass;
|
||||
|
||||
priv->base.units = nvc0_graph_units;
|
||||
|
||||
if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
|
||||
nv_info(priv, "using external firmware\n");
|
||||
if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
|
||||
|
@ -227,11 +451,13 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
priv->firmware = true;
|
||||
}
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
|
||||
&priv->unk4188b4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
|
||||
&priv->unk4188b8);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -94,6 +94,32 @@ nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd,
|
||||
void *args, u32 size)
|
||||
{
|
||||
struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
|
||||
struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine;
|
||||
u32 data = *(u32 *)args;
|
||||
|
||||
switch (mthd) {
|
||||
case 0x600:
|
||||
nv_wr32(priv, 0x419e00, data); /* MP.PM_UNK000 */
|
||||
break;
|
||||
case 0x644:
|
||||
if (data & ~0x1ffffe)
|
||||
return -EINVAL;
|
||||
nv_wr32(priv, 0x419e44, data); /* MP.TRAP_WARP_ERROR_EN */
|
||||
break;
|
||||
case 0x6ac:
|
||||
nv_wr32(priv, 0x419eac, data); /* MP.PM_UNK0AC */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct nouveau_omthds
|
||||
nvc0_software_omthds[] = {
|
||||
{ 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset },
|
||||
|
@ -101,6 +127,9 @@ nvc0_software_omthds[] = {
|
|||
{ 0x0408, 0x0408, nvc0_software_mthd_vblsem_value },
|
||||
{ 0x040c, 0x040c, nvc0_software_mthd_vblsem_release },
|
||||
{ 0x0500, 0x0500, nvc0_software_mthd_flip },
|
||||
{ 0x0600, 0x0600, nvc0_software_mthd_mp_control },
|
||||
{ 0x0644, 0x0644, nvc0_software_mthd_mp_control },
|
||||
{ 0x06ac, 0x06ac, nvc0_software_mthd_mp_control },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <core/engine.h>
|
||||
|
||||
enum nv_subdev_type {
|
||||
NVDEV_SUBDEV_DEVICE,
|
||||
NVDEV_ENGINE_DEVICE,
|
||||
NVDEV_SUBDEV_VBIOS,
|
||||
|
||||
/* All subdevs from DEVINIT to DEVINIT_LAST will be created before
|
||||
|
@ -57,7 +57,7 @@ enum nv_subdev_type {
|
|||
};
|
||||
|
||||
struct nouveau_device {
|
||||
struct nouveau_subdev base;
|
||||
struct nouveau_engine base;
|
||||
struct list_head head;
|
||||
|
||||
struct pci_dev *pdev;
|
||||
|
@ -99,7 +99,7 @@ nv_device(void *obj)
|
|||
|
||||
#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
|
||||
if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) ||
|
||||
(nv_hclass(device) & 0xff) != NVDEV_SUBDEV_DEVICE)) {
|
||||
(nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) {
|
||||
nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x",
|
||||
nv_hclass(object), nv_hclass(device));
|
||||
}
|
||||
|
|
|
@ -51,8 +51,8 @@ int nouveau_parent_create_(struct nouveau_object *, struct nouveau_object *,
|
|||
void nouveau_parent_destroy(struct nouveau_parent *);
|
||||
|
||||
void _nouveau_parent_dtor(struct nouveau_object *);
|
||||
#define _nouveau_parent_init _nouveau_object_init
|
||||
#define _nouveau_parent_fini _nouveau_object_fini
|
||||
#define _nouveau_parent_init nouveau_object_init
|
||||
#define _nouveau_parent_fini nouveau_object_fini
|
||||
|
||||
int nouveau_parent_sclass(struct nouveau_object *, u16 handle,
|
||||
struct nouveau_object **pengine,
|
||||
|
|
|
@ -18,7 +18,6 @@ int nv50_identify(struct nouveau_device *);
|
|||
int nvc0_identify(struct nouveau_device *);
|
||||
int nve0_identify(struct nouveau_device *);
|
||||
|
||||
extern struct nouveau_oclass nouveau_device_sclass[];
|
||||
struct nouveau_device *nouveau_device_find(u64 name);
|
||||
|
||||
#endif
|
|
@ -65,7 +65,8 @@ struct nouveau_fifo_base {
|
|||
struct nouveau_fifo {
|
||||
struct nouveau_engine base;
|
||||
|
||||
struct nouveau_event *uevent;
|
||||
struct nouveau_event *cevent; /* channel creation event */
|
||||
struct nouveau_event *uevent; /* async user trigger */
|
||||
|
||||
struct nouveau_object **channel;
|
||||
spinlock_t lock;
|
||||
|
|
|
@ -26,6 +26,10 @@ struct nouveau_graph_chan {
|
|||
|
||||
struct nouveau_graph {
|
||||
struct nouveau_engine base;
|
||||
|
||||
/* Returns chipset-specific counts of units packed into an u64.
|
||||
*/
|
||||
u64 (*units)(struct nouveau_graph *);
|
||||
};
|
||||
|
||||
static inline struct nouveau_graph *
|
||||
|
|
|
@ -4,8 +4,15 @@
|
|||
#include <core/subdev.h>
|
||||
#include <core/device.h>
|
||||
|
||||
struct nouveau_mm_node;
|
||||
|
||||
struct nouveau_ltcg {
|
||||
struct nouveau_subdev base;
|
||||
|
||||
int (*tags_alloc)(struct nouveau_ltcg *, u32 count,
|
||||
struct nouveau_mm_node **);
|
||||
void (*tags_free)(struct nouveau_ltcg *, struct nouveau_mm_node **);
|
||||
void (*tags_clear)(struct nouveau_ltcg *, u32 first, u32 count);
|
||||
};
|
||||
|
||||
static inline struct nouveau_ltcg *
|
||||
|
|
|
@ -21,18 +21,22 @@ nouveau_mc(void *obj)
|
|||
}
|
||||
|
||||
#define nouveau_mc_create(p,e,o,d) \
|
||||
nouveau_subdev_create_((p), (e), (o), 0, "PMC", "master", \
|
||||
sizeof(**d), (void **)d)
|
||||
#define nouveau_mc_destroy(p) \
|
||||
nouveau_subdev_destroy(&(p)->base)
|
||||
#define nouveau_mc_init(p) \
|
||||
nouveau_subdev_init(&(p)->base)
|
||||
#define nouveau_mc_fini(p,s) \
|
||||
nouveau_subdev_fini(&(p)->base, (s))
|
||||
nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
|
||||
#define nouveau_mc_destroy(p) ({ \
|
||||
struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
|
||||
})
|
||||
#define nouveau_mc_init(p) ({ \
|
||||
struct nouveau_mc *pmc = (p); _nouveau_mc_init(nv_object(pmc)); \
|
||||
})
|
||||
#define nouveau_mc_fini(p,s) ({ \
|
||||
struct nouveau_mc *pmc = (p); _nouveau_mc_fini(nv_object(pmc), (s)); \
|
||||
})
|
||||
|
||||
#define _nouveau_mc_dtor _nouveau_subdev_dtor
|
||||
#define _nouveau_mc_init _nouveau_subdev_init
|
||||
#define _nouveau_mc_fini _nouveau_subdev_fini
|
||||
int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
|
||||
struct nouveau_oclass *, int, void **);
|
||||
void _nouveau_mc_dtor(struct nouveau_object *);
|
||||
int _nouveau_mc_init(struct nouveau_object *);
|
||||
int _nouveau_mc_fini(struct nouveau_object *, bool);
|
||||
|
||||
extern struct nouveau_oclass nv04_mc_oclass;
|
||||
extern struct nouveau_oclass nv44_mc_oclass;
|
||||
|
@ -40,8 +44,6 @@ extern struct nouveau_oclass nv50_mc_oclass;
|
|||
extern struct nouveau_oclass nv98_mc_oclass;
|
||||
extern struct nouveau_oclass nvc0_mc_oclass;
|
||||
|
||||
void nouveau_mc_intr(struct nouveau_subdev *);
|
||||
|
||||
extern const struct nouveau_mc_intr nv04_mc_intr[];
|
||||
int nv04_mc_init(struct nouveau_object *);
|
||||
int nv50_mc_init(struct nouveau_object *);
|
||||
|
|
|
@ -73,6 +73,7 @@ int _nouveau_therm_fini(struct nouveau_object *, bool);
|
|||
|
||||
extern struct nouveau_oclass nv40_therm_oclass;
|
||||
extern struct nouveau_oclass nv50_therm_oclass;
|
||||
extern struct nouveau_oclass nv84_therm_oclass;
|
||||
extern struct nouveau_oclass nva3_therm_oclass;
|
||||
extern struct nouveau_oclass nvd0_therm_oclass;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
|
|
@ -122,18 +122,20 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0, NVOBJ_FLAG_HEAP,
|
||||
&priv->mem);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
|
||||
NVOBJ_FLAG_HEAP, &priv->mem);
|
||||
heap = nv_object(priv->mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, heap, (device->chipset == 0x50) ?
|
||||
0x1400 : 0x0200, 0, 0, &priv->pad);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), heap,
|
||||
(device->chipset == 0x50) ? 0x1400 : 0x0200,
|
||||
0, 0, &priv->pad);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, heap, 0x4000, 0, 0, &priv->pgd);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), heap, 0x4000, 0,
|
||||
0, &priv->pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -145,9 +147,9 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, heap, ((limit-- - start) >> 12) * 8,
|
||||
0x1000, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&vm->pgt[0].obj[0]);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), heap,
|
||||
((limit-- - start) >> 12) * 8, 0x1000,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
|
||||
vm->pgt[0].refcount[0] = 1;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -157,7 +159,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, heap, 24, 16, 0, &priv->bar3);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar3);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -182,7 +184,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, heap, 24, 16, 0, &priv->bar1);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -101,12 +101,14 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
/* BAR3 */
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0, 0, &priv->bar[0].mem);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
|
||||
&priv->bar[0].mem);
|
||||
mem = priv->bar[0].mem;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x8000, 0, 0, &priv->bar[0].pgd);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
|
||||
&priv->bar[0].pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -114,7 +116,7 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
(pci_resource_len(pdev, 3) >> 12) * 8,
|
||||
0x1000, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&vm->pgt[0].obj[0]);
|
||||
|
@ -133,12 +135,14 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1));
|
||||
|
||||
/* BAR1 */
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0, 0, &priv->bar[1].mem);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
|
||||
&priv->bar[1].mem);
|
||||
mem = priv->bar[1].mem;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x8000, 0, 0, &priv->bar[1].pgd);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
|
||||
&priv->bar[1].pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -64,27 +64,33 @@ init_exec_force(struct nvbios_init *init, bool exec)
|
|||
static inline int
|
||||
init_or(struct nvbios_init *init)
|
||||
{
|
||||
if (init->outp)
|
||||
return ffs(init->outp->or) - 1;
|
||||
error("script needs OR!!\n");
|
||||
if (init_exec(init)) {
|
||||
if (init->outp)
|
||||
return ffs(init->outp->or) - 1;
|
||||
error("script needs OR!!\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
init_link(struct nvbios_init *init)
|
||||
{
|
||||
if (init->outp)
|
||||
return !(init->outp->sorconf.link & 1);
|
||||
error("script needs OR link\n");
|
||||
if (init_exec(init)) {
|
||||
if (init->outp)
|
||||
return !(init->outp->sorconf.link & 1);
|
||||
error("script needs OR link\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
init_crtc(struct nvbios_init *init)
|
||||
{
|
||||
if (init->crtc >= 0)
|
||||
return init->crtc;
|
||||
error("script needs crtc\n");
|
||||
if (init_exec(init)) {
|
||||
if (init->crtc >= 0)
|
||||
return init->crtc;
|
||||
error("script needs crtc\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -92,16 +98,21 @@ static u8
|
|||
init_conn(struct nvbios_init *init)
|
||||
{
|
||||
struct nouveau_bios *bios = init->bios;
|
||||
u8 ver, len;
|
||||
u16 conn;
|
||||
|
||||
if (init->outp) {
|
||||
u8 ver, len;
|
||||
u16 conn = dcb_conn(bios, init->outp->connector, &ver, &len);
|
||||
if (conn)
|
||||
return nv_ro08(bios, conn);
|
||||
if (init_exec(init)) {
|
||||
if (init->outp) {
|
||||
conn = init->outp->connector;
|
||||
conn = dcb_conn(bios, conn, &ver, &len);
|
||||
if (conn)
|
||||
return nv_ro08(bios, conn);
|
||||
}
|
||||
|
||||
error("script needs connector type\n");
|
||||
}
|
||||
|
||||
error("script needs connector type\n");
|
||||
return 0x00;
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
|
@ -227,7 +238,8 @@ init_i2c(struct nvbios_init *init, int index)
|
|||
} else
|
||||
if (index < 0) {
|
||||
if (!init->outp) {
|
||||
error("script needs output for i2c\n");
|
||||
if (init_exec(init))
|
||||
error("script needs output for i2c\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -544,7 +556,8 @@ init_tmds_reg(struct nvbios_init *init, u8 tmds)
|
|||
return 0x6808b0 + dacoffset;
|
||||
}
|
||||
|
||||
error("tmds opcodes need dcb\n");
|
||||
if (init_exec(init))
|
||||
error("tmds opcodes need dcb\n");
|
||||
} else {
|
||||
if (tmds < ARRAY_SIZE(pramdac_table))
|
||||
return pramdac_table[tmds];
|
||||
|
@ -792,7 +805,8 @@ init_dp_condition(struct nvbios_init *init)
|
|||
break;
|
||||
}
|
||||
|
||||
warn("script needs dp output table data\n");
|
||||
if (init_exec(init))
|
||||
warn("script needs dp output table data\n");
|
||||
break;
|
||||
case 5:
|
||||
if (!(init_rdauxr(init, 0x0d) & 1))
|
||||
|
@ -816,7 +830,7 @@ init_io_mask_or(struct nvbios_init *init)
|
|||
u8 or = init_or(init);
|
||||
u8 data;
|
||||
|
||||
trace("IO_MASK_OR\t0x03d4[0x%02x] &= ~(1 << 0x%02x)", index, or);
|
||||
trace("IO_MASK_OR\t0x03d4[0x%02x] &= ~(1 << 0x%02x)\n", index, or);
|
||||
init->offset += 2;
|
||||
|
||||
data = init_rdvgai(init, 0x03d4, index);
|
||||
|
@ -835,7 +849,7 @@ init_io_or(struct nvbios_init *init)
|
|||
u8 or = init_or(init);
|
||||
u8 data;
|
||||
|
||||
trace("IO_OR\t0x03d4[0x%02x] |= (1 << 0x%02x)", index, or);
|
||||
trace("IO_OR\t0x03d4[0x%02x] |= (1 << 0x%02x)\n", index, or);
|
||||
init->offset += 2;
|
||||
|
||||
data = init_rdvgai(init, 0x03d4, index);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include <subdev/fb.h>
|
||||
#include <subdev/ltcg.h>
|
||||
#include <subdev/bios.h>
|
||||
|
||||
struct nvc0_fb_priv {
|
||||
|
@ -31,34 +32,14 @@ struct nvc0_fb_priv {
|
|||
dma_addr_t r100c10;
|
||||
};
|
||||
|
||||
/* 0 = unsupported
|
||||
* 1 = non-compressed
|
||||
* 3 = compressed
|
||||
*/
|
||||
static const u8 types[256] = {
|
||||
1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
|
||||
3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
|
||||
3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
|
||||
3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
|
||||
};
|
||||
extern const u8 nvc0_pte_storage_type_map[256];
|
||||
|
||||
|
||||
static bool
|
||||
nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
|
||||
{
|
||||
u8 memtype = (tile_flags & 0x0000ff00) >> 8;
|
||||
return likely((types[memtype] == 1));
|
||||
return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -130,6 +111,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
|
|||
int type = (memtype & 0x0ff);
|
||||
int back = (memtype & 0x800);
|
||||
int ret;
|
||||
const bool comp = nvc0_pte_storage_type_map[type] != type;
|
||||
|
||||
size >>= 12;
|
||||
align >>= 12;
|
||||
|
@ -142,10 +124,22 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
|
|||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&mem->regions);
|
||||
mem->memtype = type;
|
||||
mem->size = size;
|
||||
|
||||
mutex_lock(&pfb->base.mutex);
|
||||
if (comp) {
|
||||
struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
|
||||
|
||||
/* compression only works with lpages */
|
||||
if (align == (1 << (17 - 12))) {
|
||||
int n = size >> 5;
|
||||
ltcg->tags_alloc(ltcg, n, &mem->tag);
|
||||
}
|
||||
if (unlikely(!mem->tag))
|
||||
type = nvc0_pte_storage_type_map[type];
|
||||
}
|
||||
mem->memtype = type;
|
||||
|
||||
do {
|
||||
if (back)
|
||||
ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
|
||||
|
@ -168,6 +162,17 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
|
||||
{
|
||||
struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
|
||||
|
||||
if ((*pmem)->tag)
|
||||
ltcg->tags_free(ltcg, &(*pmem)->tag);
|
||||
|
||||
nv50_fb_vram_del(pfb, pmem);
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_fb_init(struct nouveau_object *object)
|
||||
{
|
||||
|
@ -178,7 +183,8 @@ nvc0_fb_init(struct nouveau_object *object)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
|
||||
if (priv->r100c10_page)
|
||||
nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -214,16 +220,16 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
priv->base.memtype_valid = nvc0_fb_memtype_valid;
|
||||
priv->base.ram.init = nvc0_fb_vram_init;
|
||||
priv->base.ram.get = nvc0_fb_vram_new;
|
||||
priv->base.ram.put = nv50_fb_vram_del;
|
||||
priv->base.ram.put = nvc0_fb_vram_del;
|
||||
|
||||
priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
|
||||
if (!priv->r100c10_page)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, 0,
|
||||
PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
|
||||
if (pci_dma_mapping_error(device->pdev, priv->r100c10))
|
||||
return -EFAULT;
|
||||
if (priv->r100c10_page) {
|
||||
priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page,
|
||||
0, PAGE_SIZE,
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
if (pci_dma_mapping_error(device->pdev, priv->r100c10))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return nouveau_fb_preinit(&priv->base);
|
||||
}
|
||||
|
|
|
@ -140,12 +140,8 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
|
|||
}
|
||||
|
||||
/* drop port's i2c subdev refcount, i2c handles this itself */
|
||||
if (ret == 0) {
|
||||
if (ret == 0)
|
||||
list_add_tail(&port->head, &i2c->ports);
|
||||
atomic_dec(&parent->refcount);
|
||||
atomic_dec(&engine->refcount);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,6 @@ nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent,
|
|||
u32 size, u32 align, struct nouveau_object **pobject)
|
||||
{
|
||||
struct nouveau_object *engine = nv_object(imem);
|
||||
struct nv04_instmem_priv *priv = (void *)(imem);
|
||||
int ret;
|
||||
|
||||
ret = nouveau_object_ctor(parent, engine, &nv04_instobj_oclass,
|
||||
|
@ -101,14 +100,6 @@ nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* INSTMEM itself creates objects to reserve (and preserve across
|
||||
* suspend/resume) various fixed data locations, each one of these
|
||||
* takes a reference on INSTMEM itself, causing it to never be
|
||||
* freed. We drop all the self-references here to avoid this.
|
||||
*/
|
||||
if (unlikely(!priv->created))
|
||||
atomic_dec(&engine->refcount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -134,27 +125,28 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
/* 0x00000-0x10000: reserve for probable vbios image */
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0, 0, &priv->vbios);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
|
||||
&priv->vbios);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 0x10000-0x18000: reserve for RAMHT */
|
||||
ret = nouveau_ramht_new(parent, NULL, 0x08000, 0, &priv->ramht);
|
||||
ret = nouveau_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x00800, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x00800, 0,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 0x18800-0x18a00: reserve for RAMRO */
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x00200, 0, 0, &priv->ramro);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x00200, 0, 0,
|
||||
&priv->ramro);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->created = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
struct nv04_instmem_priv {
|
||||
struct nouveau_instmem base;
|
||||
bool created;
|
||||
|
||||
void __iomem *iomem;
|
||||
struct nouveau_mm heap;
|
||||
|
|
|
@ -82,31 +82,33 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
/* 0x00000-0x10000: reserve for probable vbios image */
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0, 0, &priv->vbios);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
|
||||
&priv->vbios);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 0x10000-0x18000: reserve for RAMHT */
|
||||
ret = nouveau_ramht_new(parent, NULL, 0x08000, 0, &priv->ramht);
|
||||
ret = nouveau_ramht_new(nv_object(priv), NULL, 0x08000, 0,
|
||||
&priv->ramht);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 0x18000-0x18200: reserve for RAMRO
|
||||
* 0x18200-0x20000: padding
|
||||
*/
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x08000, 0, 0, &priv->ramro);
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x08000, 0, 0,
|
||||
&priv->ramro);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 0x20000-0x21000: reserve for RAMFC
|
||||
* 0x21000-0x40000: padding and some unknown crap
|
||||
*/
|
||||
ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
|
||||
NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->created = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,17 @@
|
|||
*/
|
||||
|
||||
#include <subdev/ltcg.h>
|
||||
#include <subdev/fb.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
struct nvc0_ltcg_priv {
|
||||
struct nouveau_ltcg base;
|
||||
u32 part_nr;
|
||||
u32 part_mask;
|
||||
u32 subp_nr;
|
||||
struct nouveau_mm tags;
|
||||
u32 num_tags;
|
||||
struct nouveau_mm_node *tag_ram;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -61,12 +68,105 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev)
|
|||
nv_mask(priv, 0x000640, 0x02000000, 0x00000000);
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n,
|
||||
struct nouveau_mm_node **pnode)
|
||||
{
|
||||
struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode);
|
||||
if (ret)
|
||||
*pnode = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode)
|
||||
{
|
||||
struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
|
||||
|
||||
nouveau_mm_free(&priv->tags, pnode);
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count)
|
||||
{
|
||||
struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
|
||||
u32 last = first + count - 1;
|
||||
int p, i;
|
||||
|
||||
BUG_ON((first > last) || (last >= priv->num_tags));
|
||||
|
||||
nv_wr32(priv, 0x17e8cc, first);
|
||||
nv_wr32(priv, 0x17e8d0, last);
|
||||
nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */
|
||||
|
||||
/* wait until it's finished with clearing */
|
||||
for (p = 0; p < priv->part_nr; ++p) {
|
||||
if (!(priv->part_mask & (1 << p)))
|
||||
continue;
|
||||
for (i = 0; i < priv->subp_nr; ++i)
|
||||
nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Figure out tag memory details and drop the over-cautious allocation.
|
||||
*/
|
||||
static int
|
||||
nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
|
||||
{
|
||||
u32 tag_size, tag_margin, tag_align;
|
||||
int ret;
|
||||
|
||||
nv_wr32(priv, 0x17e8d8, priv->part_nr);
|
||||
|
||||
/* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
|
||||
priv->num_tags = (pfb->ram.size >> 17) / 4;
|
||||
if (priv->num_tags > (1 << 17))
|
||||
priv->num_tags = 1 << 17; /* we have 17 bits in PTE */
|
||||
priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */
|
||||
|
||||
tag_align = priv->part_nr * 0x800;
|
||||
tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align;
|
||||
|
||||
/* 4 part 4 sub: 0x2000 bytes for 56 tags */
|
||||
/* 3 part 4 sub: 0x6000 bytes for 168 tags */
|
||||
/*
|
||||
* About 147 bytes per tag. Let's be safe and allocate x2, which makes
|
||||
* 0x4980 bytes for 64 tags, and round up to 0x6000 bytes for 64 tags.
|
||||
*
|
||||
* For 4 GiB of memory we'll have 8192 tags which makes 3 MiB, < 0.1 %.
|
||||
*/
|
||||
tag_size = (priv->num_tags / 64) * 0x6000 + tag_margin;
|
||||
tag_size += tag_align;
|
||||
tag_size = (tag_size + 0xfff) >> 12; /* round up */
|
||||
|
||||
ret = nouveau_mm_tail(&pfb->vram, 0, tag_size, tag_size, 1,
|
||||
&priv->tag_ram);
|
||||
if (ret) {
|
||||
priv->num_tags = 0;
|
||||
} else {
|
||||
u64 tag_base = (priv->tag_ram->offset << 12) + tag_margin;
|
||||
|
||||
tag_base += tag_align - 1;
|
||||
ret = do_div(tag_base, tag_align);
|
||||
|
||||
nv_wr32(priv, 0x17e8d4, tag_base);
|
||||
}
|
||||
ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 size,
|
||||
struct nouveau_object **pobject)
|
||||
{
|
||||
struct nvc0_ltcg_priv *priv;
|
||||
struct nouveau_fb *pfb = nouveau_fb(parent);
|
||||
int ret;
|
||||
|
||||
ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
|
||||
|
@ -74,19 +174,44 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 24;
|
||||
priv->part_nr = nv_rd32(priv, 0x022438);
|
||||
priv->part_mask = nv_rd32(priv, 0x022554);
|
||||
|
||||
priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
|
||||
|
||||
nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
|
||||
|
||||
ret = nvc0_ltcg_init_tag_ram(pfb, priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->base.tags_alloc = nvc0_ltcg_tags_alloc;
|
||||
priv->base.tags_free = nvc0_ltcg_tags_free;
|
||||
priv->base.tags_clear = nvc0_ltcg_tags_clear;
|
||||
|
||||
nv_subdev(priv)->intr = nvc0_ltcg_intr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_ltcg_dtor(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
|
||||
struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
|
||||
struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);
|
||||
|
||||
nouveau_mm_fini(&priv->tags);
|
||||
nouveau_mm_free(&pfb->vram, &priv->tag_ram);
|
||||
|
||||
nouveau_ltcg_destroy(ltcg);
|
||||
}
|
||||
|
||||
struct nouveau_oclass
|
||||
nvc0_ltcg_oclass = {
|
||||
.handle = NV_SUBDEV(LTCG, 0xc0),
|
||||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nvc0_ltcg_ctor,
|
||||
.dtor = _nouveau_ltcg_dtor,
|
||||
.dtor = nvc0_ltcg_dtor,
|
||||
.init = _nouveau_ltcg_init,
|
||||
.fini = _nouveau_ltcg_fini,
|
||||
},
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
|
||||
#include <subdev/mc.h>
|
||||
|
||||
void
|
||||
nouveau_mc_intr(struct nouveau_subdev *subdev)
|
||||
static irqreturn_t
|
||||
nouveau_mc_intr(int irq, void *arg)
|
||||
{
|
||||
struct nouveau_mc *pmc = nouveau_mc(subdev);
|
||||
struct nouveau_mc *pmc = arg;
|
||||
const struct nouveau_mc_intr *map = pmc->intr_map;
|
||||
struct nouveau_subdev *unit;
|
||||
u32 stat, intr;
|
||||
|
@ -35,7 +35,7 @@ nouveau_mc_intr(struct nouveau_subdev *subdev)
|
|||
intr = stat = nv_rd32(pmc, 0x000100);
|
||||
while (stat && map->stat) {
|
||||
if (stat & map->stat) {
|
||||
unit = nouveau_subdev(subdev, map->unit);
|
||||
unit = nouveau_subdev(pmc, map->unit);
|
||||
if (unit && unit->intr)
|
||||
unit->intr(unit);
|
||||
intr &= ~map->stat;
|
||||
|
@ -46,4 +46,56 @@ nouveau_mc_intr(struct nouveau_subdev *subdev)
|
|||
if (intr) {
|
||||
nv_error(pmc, "unknown intr 0x%08x\n", stat);
|
||||
}
|
||||
|
||||
return stat ? IRQ_HANDLED : IRQ_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
_nouveau_mc_fini(struct nouveau_object *object, bool suspend)
|
||||
{
|
||||
struct nouveau_mc *pmc = (void *)object;
|
||||
nv_wr32(pmc, 0x000140, 0x00000000);
|
||||
return nouveau_subdev_fini(&pmc->base, suspend);
|
||||
}
|
||||
|
||||
int
|
||||
_nouveau_mc_init(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_mc *pmc = (void *)object;
|
||||
int ret = nouveau_subdev_init(&pmc->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
nv_wr32(pmc, 0x000140, 0x00000001);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_nouveau_mc_dtor(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_device *device = nv_device(object);
|
||||
struct nouveau_mc *pmc = (void *)object;
|
||||
free_irq(device->pdev->irq, pmc);
|
||||
nouveau_subdev_destroy(&pmc->base);
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, int length, void **pobject)
|
||||
{
|
||||
struct nouveau_device *device = nv_device(parent);
|
||||
struct nouveau_mc *pmc;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC",
|
||||
"master", length, pobject);
|
||||
pmc = *pobject;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = request_irq(device->pdev->irq, nouveau_mc_intr,
|
||||
IRQF_SHARED, "nouveau", pmc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_subdev(priv)->intr = nouveau_mc_intr;
|
||||
priv->base.intr_map = nv04_mc_intr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_subdev(priv)->intr = nouveau_mc_intr;
|
||||
priv->base.intr_map = nv04_mc_intr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_subdev(priv)->intr = nouveau_mc_intr;
|
||||
priv->base.intr_map = nv50_mc_intr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_subdev(priv)->intr = nouveau_mc_intr;
|
||||
priv->base.intr_map = nv98_mc_intr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,6 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_subdev(priv)->intr = nouveau_mc_intr;
|
||||
priv->base.intr_map = nvc0_mc_intr;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
nv40_therm_intr(struct nouveau_subdev *subdev)
|
||||
{
|
||||
struct nouveau_therm *therm = nouveau_therm(subdev);
|
||||
|
|
|
@ -118,145 +118,36 @@ nv50_fan_pwm_clock(struct nouveau_therm *therm)
|
|||
return pwm_clock;
|
||||
}
|
||||
|
||||
int
|
||||
static void
|
||||
nv50_sensor_setup(struct nouveau_therm *therm)
|
||||
{
|
||||
nv_mask(therm, 0x20010, 0x40000000, 0x0);
|
||||
mdelay(20); /* wait for the temperature to stabilize */
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_temp_get(struct nouveau_therm *therm)
|
||||
{
|
||||
return nv_rd32(therm, 0x20400);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_therm_program_alarms(struct nouveau_therm *therm)
|
||||
{
|
||||
struct nouveau_therm_priv *priv = (void *)therm;
|
||||
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
|
||||
unsigned long flags;
|
||||
int core_temp;
|
||||
|
||||
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
|
||||
core_temp = nv_rd32(therm, 0x20014) & 0x3fff;
|
||||
|
||||
/* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */
|
||||
nv_wr32(therm, 0x20000, 0x000003ff);
|
||||
/* if the slope or the offset is unset, do no use the sensor */
|
||||
if (!sensor->slope_div || !sensor->slope_mult ||
|
||||
!sensor->offset_num || !sensor->offset_den)
|
||||
return -ENODEV;
|
||||
|
||||
/* shutdown: The computer should be shutdown when reached */
|
||||
nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis);
|
||||
nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp);
|
||||
core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
|
||||
core_temp = core_temp + sensor->offset_num / sensor->offset_den;
|
||||
core_temp = core_temp + sensor->offset_constant - 8;
|
||||
|
||||
/* THRS_1 : fan boost*/
|
||||
nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp);
|
||||
/* reserve negative temperatures for errors */
|
||||
if (core_temp < 0)
|
||||
core_temp = 0;
|
||||
|
||||
/* THRS_2 : critical */
|
||||
nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp);
|
||||
|
||||
/* THRS_4 : down clock */
|
||||
nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp);
|
||||
spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
|
||||
|
||||
nv_info(therm,
|
||||
"Programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
|
||||
sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
|
||||
sensor->thrs_down_clock.temp,
|
||||
sensor->thrs_down_clock.hysteresis,
|
||||
sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
|
||||
sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
|
||||
|
||||
}
|
||||
|
||||
/* must be called with alarm_program_lock taken ! */
|
||||
static void
|
||||
nv50_therm_threshold_hyst_emulation(struct nouveau_therm *therm,
|
||||
uint32_t thrs_reg, u8 status_bit,
|
||||
const struct nvbios_therm_threshold *thrs,
|
||||
enum nouveau_therm_thrs thrs_name)
|
||||
{
|
||||
enum nouveau_therm_thrs_direction direction;
|
||||
enum nouveau_therm_thrs_state prev_state, new_state;
|
||||
int temp, cur;
|
||||
|
||||
prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name);
|
||||
temp = nv_rd32(therm, thrs_reg);
|
||||
|
||||
/* program the next threshold */
|
||||
if (temp == thrs->temp) {
|
||||
nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis);
|
||||
new_state = NOUVEAU_THERM_THRS_HIGHER;
|
||||
} else {
|
||||
nv_wr32(therm, thrs_reg, thrs->temp);
|
||||
new_state = NOUVEAU_THERM_THRS_LOWER;
|
||||
}
|
||||
|
||||
/* fix the state (in case someone reprogrammed the alarms) */
|
||||
cur = therm->temp_get(therm);
|
||||
if (new_state == NOUVEAU_THERM_THRS_LOWER && cur > thrs->temp)
|
||||
new_state = NOUVEAU_THERM_THRS_HIGHER;
|
||||
else if (new_state == NOUVEAU_THERM_THRS_HIGHER &&
|
||||
cur < thrs->temp - thrs->hysteresis)
|
||||
new_state = NOUVEAU_THERM_THRS_LOWER;
|
||||
nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
|
||||
|
||||
/* find the direction */
|
||||
if (prev_state < new_state)
|
||||
direction = NOUVEAU_THERM_THRS_RISING;
|
||||
else if (prev_state > new_state)
|
||||
direction = NOUVEAU_THERM_THRS_FALLING;
|
||||
else
|
||||
return;
|
||||
|
||||
/* advertise a change in direction */
|
||||
nouveau_therm_sensor_event(therm, thrs_name, direction);
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_therm_intr(struct nouveau_subdev *subdev)
|
||||
{
|
||||
struct nouveau_therm *therm = nouveau_therm(subdev);
|
||||
struct nouveau_therm_priv *priv = (void *)therm;
|
||||
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
|
||||
unsigned long flags;
|
||||
uint32_t intr;
|
||||
|
||||
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
|
||||
|
||||
intr = nv_rd32(therm, 0x20100);
|
||||
|
||||
/* THRS_4: downclock */
|
||||
if (intr & 0x002) {
|
||||
nv50_therm_threshold_hyst_emulation(therm, 0x20414, 24,
|
||||
&sensor->thrs_down_clock,
|
||||
NOUVEAU_THERM_THRS_DOWNCLOCK);
|
||||
intr &= ~0x002;
|
||||
}
|
||||
|
||||
/* shutdown */
|
||||
if (intr & 0x004) {
|
||||
nv50_therm_threshold_hyst_emulation(therm, 0x20480, 20,
|
||||
&sensor->thrs_shutdown,
|
||||
NOUVEAU_THERM_THRS_SHUTDOWN);
|
||||
intr &= ~0x004;
|
||||
}
|
||||
|
||||
/* THRS_1 : fan boost */
|
||||
if (intr & 0x008) {
|
||||
nv50_therm_threshold_hyst_emulation(therm, 0x204c4, 21,
|
||||
&sensor->thrs_fan_boost,
|
||||
NOUVEAU_THERM_THRS_FANBOOST);
|
||||
intr &= ~0x008;
|
||||
}
|
||||
|
||||
/* THRS_2 : critical */
|
||||
if (intr & 0x010) {
|
||||
nv50_therm_threshold_hyst_emulation(therm, 0x204c0, 22,
|
||||
&sensor->thrs_critical,
|
||||
NOUVEAU_THERM_THRS_CRITICAL);
|
||||
intr &= ~0x010;
|
||||
}
|
||||
|
||||
if (intr)
|
||||
nv_error(therm, "unhandled intr 0x%08x\n", intr);
|
||||
|
||||
/* ACK everything */
|
||||
nv_wr32(therm, 0x20100, 0xffffffff);
|
||||
nv_wr32(therm, 0x1100, 0x10000); /* PBUS */
|
||||
|
||||
spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
|
||||
return core_temp;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -278,33 +169,29 @@ nv50_therm_ctor(struct nouveau_object *parent,
|
|||
priv->base.base.pwm_set = nv50_fan_pwm_set;
|
||||
priv->base.base.pwm_clock = nv50_fan_pwm_clock;
|
||||
priv->base.base.temp_get = nv50_temp_get;
|
||||
priv->base.sensor.program_alarms = nv50_therm_program_alarms;
|
||||
nv_subdev(priv)->intr = nv50_therm_intr;
|
||||
|
||||
/* init the thresholds */
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_SHUTDOWN,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_FANBOOST,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_CRITICAL,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_DOWNCLOCK,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
|
||||
nv_subdev(priv)->intr = nv40_therm_intr;
|
||||
|
||||
return nouveau_therm_preinit(&priv->base.base);
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_therm_init(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_therm *therm = (void *)object;
|
||||
|
||||
nv50_sensor_setup(therm);
|
||||
|
||||
return _nouveau_therm_init(object);
|
||||
}
|
||||
|
||||
struct nouveau_oclass
|
||||
nv50_therm_oclass = {
|
||||
.handle = NV_SUBDEV(THERM, 0x50),
|
||||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nv50_therm_ctor,
|
||||
.dtor = _nouveau_therm_dtor,
|
||||
.init = _nouveau_therm_init,
|
||||
.init = nv50_therm_init,
|
||||
.fini = _nouveau_therm_fini,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright 2012 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
* Martin Peres
|
||||
*/
|
||||
|
||||
#include "priv.h"
|
||||
|
||||
struct nv84_therm_priv {
|
||||
struct nouveau_therm_priv base;
|
||||
};
|
||||
|
||||
int
|
||||
nv84_temp_get(struct nouveau_therm *therm)
|
||||
{
|
||||
return nv_rd32(therm, 0x20400);
|
||||
}
|
||||
|
||||
static void
|
||||
nv84_therm_program_alarms(struct nouveau_therm *therm)
|
||||
{
|
||||
struct nouveau_therm_priv *priv = (void *)therm;
|
||||
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
|
||||
|
||||
/* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */
|
||||
nv_wr32(therm, 0x20000, 0x000003ff);
|
||||
|
||||
/* shutdown: The computer should be shutdown when reached */
|
||||
nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis);
|
||||
nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp);
|
||||
|
||||
/* THRS_1 : fan boost*/
|
||||
nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp);
|
||||
|
||||
/* THRS_2 : critical */
|
||||
nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp);
|
||||
|
||||
/* THRS_4 : down clock */
|
||||
nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp);
|
||||
spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
|
||||
|
||||
nv_debug(therm,
|
||||
"Programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
|
||||
sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
|
||||
sensor->thrs_down_clock.temp,
|
||||
sensor->thrs_down_clock.hysteresis,
|
||||
sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
|
||||
sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
|
||||
|
||||
}
|
||||
|
||||
/* must be called with alarm_program_lock taken ! */
|
||||
static void
|
||||
nv84_therm_threshold_hyst_emulation(struct nouveau_therm *therm,
|
||||
uint32_t thrs_reg, u8 status_bit,
|
||||
const struct nvbios_therm_threshold *thrs,
|
||||
enum nouveau_therm_thrs thrs_name)
|
||||
{
|
||||
enum nouveau_therm_thrs_direction direction;
|
||||
enum nouveau_therm_thrs_state prev_state, new_state;
|
||||
int temp, cur;
|
||||
|
||||
prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name);
|
||||
temp = nv_rd32(therm, thrs_reg);
|
||||
|
||||
/* program the next threshold */
|
||||
if (temp == thrs->temp) {
|
||||
nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis);
|
||||
new_state = NOUVEAU_THERM_THRS_HIGHER;
|
||||
} else {
|
||||
nv_wr32(therm, thrs_reg, thrs->temp);
|
||||
new_state = NOUVEAU_THERM_THRS_LOWER;
|
||||
}
|
||||
|
||||
/* fix the state (in case someone reprogrammed the alarms) */
|
||||
cur = therm->temp_get(therm);
|
||||
if (new_state == NOUVEAU_THERM_THRS_LOWER && cur > thrs->temp)
|
||||
new_state = NOUVEAU_THERM_THRS_HIGHER;
|
||||
else if (new_state == NOUVEAU_THERM_THRS_HIGHER &&
|
||||
cur < thrs->temp - thrs->hysteresis)
|
||||
new_state = NOUVEAU_THERM_THRS_LOWER;
|
||||
nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
|
||||
|
||||
/* find the direction */
|
||||
if (prev_state < new_state)
|
||||
direction = NOUVEAU_THERM_THRS_RISING;
|
||||
else if (prev_state > new_state)
|
||||
direction = NOUVEAU_THERM_THRS_FALLING;
|
||||
else
|
||||
return;
|
||||
|
||||
/* advertise a change in direction */
|
||||
nouveau_therm_sensor_event(therm, thrs_name, direction);
|
||||
}
|
||||
|
||||
static void
|
||||
nv84_therm_intr(struct nouveau_subdev *subdev)
|
||||
{
|
||||
struct nouveau_therm *therm = nouveau_therm(subdev);
|
||||
struct nouveau_therm_priv *priv = (void *)therm;
|
||||
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
|
||||
unsigned long flags;
|
||||
uint32_t intr;
|
||||
|
||||
spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
|
||||
|
||||
intr = nv_rd32(therm, 0x20100);
|
||||
|
||||
/* THRS_4: downclock */
|
||||
if (intr & 0x002) {
|
||||
nv84_therm_threshold_hyst_emulation(therm, 0x20414, 24,
|
||||
&sensor->thrs_down_clock,
|
||||
NOUVEAU_THERM_THRS_DOWNCLOCK);
|
||||
intr &= ~0x002;
|
||||
}
|
||||
|
||||
/* shutdown */
|
||||
if (intr & 0x004) {
|
||||
nv84_therm_threshold_hyst_emulation(therm, 0x20480, 20,
|
||||
&sensor->thrs_shutdown,
|
||||
NOUVEAU_THERM_THRS_SHUTDOWN);
|
||||
intr &= ~0x004;
|
||||
}
|
||||
|
||||
/* THRS_1 : fan boost */
|
||||
if (intr & 0x008) {
|
||||
nv84_therm_threshold_hyst_emulation(therm, 0x204c4, 21,
|
||||
&sensor->thrs_fan_boost,
|
||||
NOUVEAU_THERM_THRS_FANBOOST);
|
||||
intr &= ~0x008;
|
||||
}
|
||||
|
||||
/* THRS_2 : critical */
|
||||
if (intr & 0x010) {
|
||||
nv84_therm_threshold_hyst_emulation(therm, 0x204c0, 22,
|
||||
&sensor->thrs_critical,
|
||||
NOUVEAU_THERM_THRS_CRITICAL);
|
||||
intr &= ~0x010;
|
||||
}
|
||||
|
||||
if (intr)
|
||||
nv_error(therm, "unhandled intr 0x%08x\n", intr);
|
||||
|
||||
/* ACK everything */
|
||||
nv_wr32(therm, 0x20100, 0xffffffff);
|
||||
nv_wr32(therm, 0x1100, 0x10000); /* PBUS */
|
||||
|
||||
spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
nv84_therm_ctor(struct nouveau_object *parent,
|
||||
struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 size,
|
||||
struct nouveau_object **pobject)
|
||||
{
|
||||
struct nv84_therm_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_therm_create(parent, engine, oclass, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->base.base.pwm_ctrl = nv50_fan_pwm_ctrl;
|
||||
priv->base.base.pwm_get = nv50_fan_pwm_get;
|
||||
priv->base.base.pwm_set = nv50_fan_pwm_set;
|
||||
priv->base.base.pwm_clock = nv50_fan_pwm_clock;
|
||||
priv->base.base.temp_get = nv84_temp_get;
|
||||
priv->base.sensor.program_alarms = nv84_therm_program_alarms;
|
||||
nv_subdev(priv)->intr = nv84_therm_intr;
|
||||
|
||||
/* init the thresholds */
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_SHUTDOWN,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_FANBOOST,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_CRITICAL,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
nouveau_therm_sensor_set_threshold_state(&priv->base.base,
|
||||
NOUVEAU_THERM_THRS_DOWNCLOCK,
|
||||
NOUVEAU_THERM_THRS_LOWER);
|
||||
|
||||
return nouveau_therm_preinit(&priv->base.base);
|
||||
}
|
||||
|
||||
struct nouveau_oclass
|
||||
nv84_therm_oclass = {
|
||||
.handle = NV_SUBDEV(THERM, 0x84),
|
||||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nv84_therm_ctor,
|
||||
.dtor = _nouveau_therm_dtor,
|
||||
.init = _nouveau_therm_init,
|
||||
.fini = _nouveau_therm_fini,
|
||||
},
|
||||
};
|
|
@ -81,7 +81,7 @@ nva3_therm_ctor(struct nouveau_object *parent,
|
|||
priv->base.base.pwm_get = nv50_fan_pwm_get;
|
||||
priv->base.base.pwm_set = nv50_fan_pwm_set;
|
||||
priv->base.base.pwm_clock = nv50_fan_pwm_clock;
|
||||
priv->base.base.temp_get = nv50_temp_get;
|
||||
priv->base.base.temp_get = nv84_temp_get;
|
||||
priv->base.base.fan_sense = nva3_therm_fan_sense;
|
||||
priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
|
||||
return nouveau_therm_preinit(&priv->base.base);
|
||||
|
|
|
@ -135,7 +135,7 @@ nvd0_therm_ctor(struct nouveau_object *parent,
|
|||
priv->base.base.pwm_get = nvd0_fan_pwm_get;
|
||||
priv->base.base.pwm_set = nvd0_fan_pwm_set;
|
||||
priv->base.base.pwm_clock = nvd0_fan_pwm_clock;
|
||||
priv->base.base.temp_get = nv50_temp_get;
|
||||
priv->base.base.temp_get = nv84_temp_get;
|
||||
priv->base.base.fan_sense = nva3_therm_fan_sense;
|
||||
priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
|
||||
return nouveau_therm_preinit(&priv->base.base);
|
||||
|
|
|
@ -134,11 +134,12 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
|
|||
enum nouveau_therm_thrs_direction dir);
|
||||
void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm);
|
||||
|
||||
void nv40_therm_intr(struct nouveau_subdev *);
|
||||
int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool);
|
||||
int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *);
|
||||
int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32);
|
||||
int nv50_fan_pwm_clock(struct nouveau_therm *);
|
||||
int nv50_temp_get(struct nouveau_therm *therm);
|
||||
int nv84_temp_get(struct nouveau_therm *therm);
|
||||
|
||||
int nva3_therm_fan_sense(struct nouveau_therm *);
|
||||
|
||||
|
|
|
@ -205,13 +205,13 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm)
|
|||
struct nouveau_therm_priv *priv = (void *)therm;
|
||||
struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
|
||||
|
||||
nv_info(therm,
|
||||
"programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
|
||||
sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
|
||||
sensor->thrs_down_clock.temp,
|
||||
sensor->thrs_down_clock.hysteresis,
|
||||
sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
|
||||
sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
|
||||
nv_debug(therm,
|
||||
"programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
|
||||
sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
|
||||
sensor->thrs_down_clock.temp,
|
||||
sensor->thrs_down_clock.hysteresis,
|
||||
sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
|
||||
sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
|
||||
|
||||
alarm_timer_callback(&priv->sensor.therm_poll_alarm);
|
||||
}
|
||||
|
|
|
@ -96,11 +96,16 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
|
|||
|
||||
/* append new alarm to list, in soonest-alarm-first order */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
list_for_each_entry(list, &priv->alarms, head) {
|
||||
if (list->timestamp > alarm->timestamp)
|
||||
break;
|
||||
if (!time) {
|
||||
if (!list_empty(&alarm->head))
|
||||
list_del(&alarm->head);
|
||||
} else {
|
||||
list_for_each_entry(list, &priv->alarms, head) {
|
||||
if (list->timestamp > alarm->timestamp)
|
||||
break;
|
||||
}
|
||||
list_add_tail(&alarm->head, &list->head);
|
||||
}
|
||||
list_add_tail(&alarm->head, &list->head);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
/* process pending alarms */
|
||||
|
|
|
@ -110,7 +110,7 @@ nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
(NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 +
|
||||
8, 16, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&priv->vm->pgt[0].obj[0]);
|
||||
|
|
|
@ -119,7 +119,7 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
(NV41_GART_SIZE / NV41_GART_PAGE) * 4,
|
||||
16, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&priv->vm->pgt[0].obj[0]);
|
||||
|
|
|
@ -196,7 +196,7 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(parent, NULL,
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
(NV44_GART_SIZE / NV44_GART_PAGE) * 4,
|
||||
512 * 1024, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&priv->vm->pgt[0].obj[0]);
|
||||
|
|
|
@ -28,12 +28,54 @@
|
|||
#include <subdev/timer.h>
|
||||
#include <subdev/fb.h>
|
||||
#include <subdev/vm.h>
|
||||
#include <subdev/ltcg.h>
|
||||
|
||||
struct nvc0_vmmgr_priv {
|
||||
struct nouveau_vmmgr base;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
||||
/* Map from compressed to corresponding uncompressed storage type.
|
||||
* The value 0xff represents an invalid storage type.
|
||||
*/
|
||||
const u8 nvc0_pte_storage_type_map[256] =
|
||||
{
|
||||
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */
|
||||
0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, /* 0x10 */
|
||||
0x11, 0x11, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x27, /* 0x20 */
|
||||
0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 */
|
||||
0xff, 0xff, 0x26, 0x27, 0x28, 0x29, 0x26, 0x27,
|
||||
0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, /* 0x40 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x46, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, /* 0x50 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x60 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */
|
||||
0xff, 0xff, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x7b, /* 0x80 */
|
||||
0x7b, 0x7b, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xa7, /* 0xa0 */
|
||||
0xa8, 0xa9, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xc3, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
|
||||
0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xc3, 0xc3,
|
||||
0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
|
||||
0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe,
|
||||
0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, /* 0xe0 */
|
||||
0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xf0 */
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index,
|
||||
struct nouveau_gpuobj *pgt[2])
|
||||
|
@ -68,10 +110,20 @@ static void
|
|||
nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
|
||||
struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
|
||||
{
|
||||
u32 next = 1 << (vma->node->type - 8);
|
||||
u64 next = 1 << (vma->node->type - 8);
|
||||
|
||||
phys = nvc0_vm_addr(vma, phys, mem->memtype, 0);
|
||||
pte <<= 3;
|
||||
|
||||
if (mem->tag) {
|
||||
struct nouveau_ltcg *ltcg =
|
||||
nouveau_ltcg(vma->vm->vmm->base.base.parent);
|
||||
u32 tag = mem->tag->offset + (delta >> 17);
|
||||
phys |= (u64)tag << (32 + 12);
|
||||
next |= (u64)1 << (32 + 12);
|
||||
ltcg->tags_clear(ltcg, tag, cnt);
|
||||
}
|
||||
|
||||
while (cnt--) {
|
||||
nv_wo32(pgt, pte + 0, lower_32_bits(phys));
|
||||
nv_wo32(pgt, pte + 4, upper_32_bits(phys));
|
||||
|
@ -85,10 +137,12 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
|
|||
struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
|
||||
{
|
||||
u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
|
||||
/* compressed storage types are invalid for system memory */
|
||||
u32 memtype = nvc0_pte_storage_type_map[mem->memtype & 0xff];
|
||||
|
||||
pte <<= 3;
|
||||
while (cnt--) {
|
||||
u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, target);
|
||||
u64 phys = nvc0_vm_addr(vma, *list++, memtype, target);
|
||||
nv_wo32(pgt, pte + 0, lower_32_bits(phys));
|
||||
nv_wo32(pgt, pte + 4, upper_32_bits(phys));
|
||||
pte += 8;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
nouveau-y += dispnv04/arb.o
|
||||
nouveau-y += dispnv04/crtc.o
|
||||
nouveau-y += dispnv04/cursor.o
|
||||
nouveau-y += dispnv04/dac.o
|
||||
nouveau-y += dispnv04/dfp.o
|
||||
nouveau-y += dispnv04/disp.o
|
||||
nouveau-y += dispnv04/hw.o
|
||||
nouveau-y += dispnv04/tvmodesnv17.o
|
||||
nouveau-y += dispnv04/tvnv04.o
|
||||
nouveau-y += dispnv04/tvnv17.o
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
|
||||
/****************************************************************************\
|
||||
* *
|
|
@ -33,10 +33,10 @@
|
|||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
#include "nvreg.h"
|
||||
#include "nouveau_fbcon.h"
|
||||
#include "nv04_display.h"
|
||||
#include "disp.h"
|
||||
|
||||
#include <subdev/bios/pll.h>
|
||||
#include <subdev/clock.h>
|
||||
|
@ -1070,4 +1070,3 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#include "nouveau_drm.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
|
||||
static void
|
||||
nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
|
||||
|
@ -68,4 +68,3 @@ nv04_cursor_init(struct nouveau_crtc *crtc)
|
|||
crtc->cursor.show = nv04_cursor_show;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
#include "nvreg.h"
|
||||
|
||||
#include <subdev/bios/gpio.h>
|
|
@ -32,7 +32,7 @@
|
|||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
#include "nvreg.h"
|
||||
|
||||
#include <drm/i2c/sil164.h>
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <drm/drmP.h>
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
|
||||
#include <subdev/bios/pll.h>
|
||||
#include <subdev/clock.h>
|
|
@ -24,7 +24,8 @@
|
|||
#define __NOUVEAU_HW_H__
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include "nv04_display.h"
|
||||
#include "disp.h"
|
||||
#include "nvreg.h"
|
||||
|
||||
#include <subdev/bios/pll.h>
|
||||
|
|
@ -29,8 +29,8 @@
|
|||
#include "nouveau_drm.h"
|
||||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "nv17_tv.h"
|
||||
#include "hw.h"
|
||||
#include "tvnv17.h"
|
||||
|
||||
char *nv17_tv_norm_names[NUM_TV_NORMS] = {
|
||||
[TV_NORM_PAL] = "PAL",
|
|
@ -30,7 +30,7 @@
|
|||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "hw.h"
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
#include <drm/i2c/ch7006.h>
|
|
@ -31,8 +31,8 @@
|
|||
#include "nouveau_encoder.h"
|
||||
#include "nouveau_connector.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "nv17_tv.h"
|
||||
#include "hw.h"
|
||||
#include "tvnv17.h"
|
||||
|
||||
#include <core/device.h>
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#include <subdev/fb.h>
|
||||
#include <subdev/timer.h>
|
||||
#include <subdev/instmem.h>
|
||||
#include <engine/graph.h>
|
||||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_dma.h"
|
||||
|
@ -168,6 +169,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
|
|||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
struct nouveau_device *device = nv_device(drm->device);
|
||||
struct nouveau_timer *ptimer = nouveau_timer(device);
|
||||
struct nouveau_graph *graph = (void *)nouveau_engine(device, NVDEV_ENGINE_GR);
|
||||
struct drm_nouveau_getparam *getparam = data;
|
||||
|
||||
switch (getparam->param) {
|
||||
|
@ -208,14 +210,8 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
|
|||
getparam->value = 1;
|
||||
break;
|
||||
case NOUVEAU_GETPARAM_GRAPH_UNITS:
|
||||
/* NV40 and NV50 versions are quite different, but register
|
||||
* address is the same. User is supposed to know the card
|
||||
* family anyway... */
|
||||
if (device->chipset >= 0x40) {
|
||||
getparam->value = nv_rd32(device, 0x001540);
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
getparam->value = graph->units ? graph->units(graph) : 0;
|
||||
break;
|
||||
default:
|
||||
nv_debug(device, "unknown parameter %lld\n", getparam->param);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -239,6 +239,9 @@ nouveau_backlight_init(struct drm_device *dev)
|
|||
case NV_40:
|
||||
return nv40_backlight_init(connector);
|
||||
case NV_50:
|
||||
case NV_C0:
|
||||
case NV_D0:
|
||||
case NV_E0:
|
||||
return nv50_backlight_init(connector);
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "dispnv04/hw.h"
|
||||
#include "nouveau_encoder.h"
|
||||
|
||||
#include <linux/io-mapping.h>
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#ifndef __NOUVEAU_DISPBIOS_H__
|
||||
#define __NOUVEAU_DISPBIOS_H__
|
||||
|
||||
#include "nvreg.h"
|
||||
|
||||
#define DCB_MAX_NUM_ENTRIES 16
|
||||
#define DCB_MAX_NUM_I2C_ENTRIES 16
|
||||
#define DCB_MAX_NUM_GPIO_ENTRIES 32
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "dispnv04/hw.h"
|
||||
#include "nouveau_acpi.h"
|
||||
|
||||
#include "nouveau_display.h"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
#include "nouveau_fbcon.h"
|
||||
#include "nouveau_hw.h"
|
||||
#include "dispnv04/hw.h"
|
||||
#include "nouveau_crtc.h"
|
||||
#include "nouveau_dma.h"
|
||||
#include "nouveau_gem.h"
|
||||
|
|
|
@ -31,13 +31,12 @@
|
|||
#include <core/gpuobj.h>
|
||||
#include <core/class.h>
|
||||
|
||||
#include <subdev/device.h>
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/disp.h>
|
||||
|
||||
#include <subdev/vm.h>
|
||||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_irq.h"
|
||||
#include "nouveau_dma.h"
|
||||
#include "nouveau_ttm.h"
|
||||
#include "nouveau_gem.h"
|
||||
|
@ -365,10 +364,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
|
|||
if (ret)
|
||||
goto fail_bios;
|
||||
|
||||
ret = nouveau_irq_init(dev);
|
||||
if (ret)
|
||||
goto fail_irq;
|
||||
|
||||
ret = nouveau_display_create(dev);
|
||||
if (ret)
|
||||
goto fail_dispctor;
|
||||
|
@ -388,8 +383,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
|
|||
fail_dispinit:
|
||||
nouveau_display_destroy(dev);
|
||||
fail_dispctor:
|
||||
nouveau_irq_fini(dev);
|
||||
fail_irq:
|
||||
nouveau_bios_takedown(dev);
|
||||
fail_bios:
|
||||
nouveau_ttm_fini(drm);
|
||||
|
@ -415,7 +408,6 @@ nouveau_drm_unload(struct drm_device *dev)
|
|||
nouveau_display_fini(dev);
|
||||
nouveau_display_destroy(dev);
|
||||
|
||||
nouveau_irq_fini(dev);
|
||||
nouveau_bios_takedown(dev);
|
||||
|
||||
nouveau_ttm_fini(drm);
|
||||
|
@ -533,7 +525,6 @@ nouveau_do_resume(struct drm_device *dev)
|
|||
nouveau_fence(drm)->resume(drm);
|
||||
|
||||
nouveau_run_vbios_init(dev);
|
||||
nouveau_irq_postinstall(dev);
|
||||
nouveau_pm_resume(dev);
|
||||
|
||||
if (dev->mode_config.num_crtc) {
|
||||
|
@ -669,8 +660,7 @@ static struct drm_driver
|
|||
driver = {
|
||||
.driver_features =
|
||||
DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
|
||||
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
|
||||
DRIVER_MODESET | DRIVER_PRIME,
|
||||
DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME,
|
||||
|
||||
.load = nouveau_drm_load,
|
||||
.unload = nouveau_drm_unload,
|
||||
|
@ -684,11 +674,6 @@ driver = {
|
|||
.debugfs_cleanup = nouveau_debugfs_takedown,
|
||||
#endif
|
||||
|
||||
.irq_preinstall = nouveau_irq_preinstall,
|
||||
.irq_postinstall = nouveau_irq_postinstall,
|
||||
.irq_uninstall = nouveau_irq_uninstall,
|
||||
.irq_handler = nouveau_irq_handler,
|
||||
|
||||
.get_vblank_counter = drm_vblank_count,
|
||||
.enable_vblank = nouveau_drm_vblank_enable,
|
||||
.disable_vblank = nouveau_drm_vblank_disable,
|
||||
|
|
|
@ -10,7 +10,18 @@
|
|||
|
||||
#define DRIVER_MAJOR 1
|
||||
#define DRIVER_MINOR 1
|
||||
#define DRIVER_PATCHLEVEL 0
|
||||
#define DRIVER_PATCHLEVEL 1
|
||||
|
||||
/*
|
||||
* 1.1.1:
|
||||
* - added support for tiled system memory buffer objects
|
||||
* - added support for NOUVEAU_GETPARAM_GRAPH_UNITS on [nvc0,nve0].
|
||||
* - added support for compressed memory storage types on [nvc0,nve0].
|
||||
* - added support for software methods 0x600,0x644,0x6ac on nvc0
|
||||
* to control registers on the MPs to enable performance counters,
|
||||
* and to control the warp error enable mask (OpenGL requires out of
|
||||
* bounds access to local memory to be silently ignored / return 0).
|
||||
*/
|
||||
|
||||
#include <core/client.h>
|
||||
#include <core/event.h>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <subdev/bios/dcb.h>
|
||||
|
||||
#include <drm/drm_encoder_slave.h>
|
||||
#include "nv04_display.h"
|
||||
#include "dispnv04/disp.h"
|
||||
|
||||
#define NV_DPMS_CLEARED 0x80
|
||||
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <subdev/mc.h>
|
||||
|
||||
#include "nouveau_drm.h"
|
||||
#include "nouveau_irq.h"
|
||||
#include "nv50_display.h"
|
||||
|
||||
void
|
||||
nouveau_irq_preinstall(struct drm_device *dev)
|
||||
{
|
||||
nv_wr32(nouveau_dev(dev), 0x000140, 0x00000000);
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_irq_postinstall(struct drm_device *dev)
|
||||
{
|
||||
nv_wr32(nouveau_dev(dev), 0x000140, 0x00000001);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_irq_uninstall(struct drm_device *dev)
|
||||
{
|
||||
nv_wr32(nouveau_dev(dev), 0x000140, 0x00000000);
|
||||
}
|
||||
|
||||
irqreturn_t
|
||||
nouveau_irq_handler(DRM_IRQ_ARGS)
|
||||
{
|
||||
struct drm_device *dev = arg;
|
||||
struct nouveau_device *device = nouveau_dev(dev);
|
||||
struct nouveau_mc *pmc = nouveau_mc(device);
|
||||
u32 stat;
|
||||
|
||||
stat = nv_rd32(device, 0x000100);
|
||||
if (stat == 0 || stat == ~0)
|
||||
return IRQ_NONE;
|
||||
|
||||
nv_subdev(pmc)->intr(nv_subdev(pmc));
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_irq_init(struct drm_device *dev)
|
||||
{
|
||||
return drm_irq_install(dev);
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_irq_fini(struct drm_device *dev)
|
||||
{
|
||||
drm_irq_uninstall(dev);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue