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:
Dave Airlie 2013-04-26 15:42:02 +10:00
commit 36d9b1541c
105 changed files with 1318 additions and 646 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 },
{}
};

View File

@ -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));
}

View File

@ -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,

View File

@ -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

View File

@ -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;

View File

@ -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 *

View File

@ -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 *

View File

@ -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 *);

View File

@ -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;

View File

@ -17,6 +17,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>
#include <asm/unaligned.h>

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -9,7 +9,6 @@
struct nv04_instmem_priv {
struct nouveau_instmem base;
bool created;
void __iomem *iomem;
struct nouveau_mm heap;

View File

@ -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;
}

View File

@ -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,
},

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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,
},
};

View File

@ -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,
},
};

View File

@ -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);

View File

@ -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);

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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 */

View File

@ -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]);

View File

@ -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]);

View File

@ -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]);

View File

@ -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;

View File

@ -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

View File

@ -25,7 +25,7 @@
#include "nouveau_drm.h"
#include "nouveau_reg.h"
#include "nouveau_hw.h"
#include "hw.h"
/****************************************************************************\
* *

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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",

View File

@ -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>

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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,

View File

@ -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>

View File

@ -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

View File

@ -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