diff options
author | Dave Airlie <airlied@redhat.com> | 2013-04-26 15:42:02 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-04-26 15:42:02 +1000 |
commit | 36d9b1541cedecd59e9d8fff0bbf9b7e9dd9704e (patch) | |
tree | 3472ef1eb4c63ecd0b8e98188b42bad9b6c55ad3 | |
parent | a90b590e957d66ea357aeff4cee8425f2567ed33 (diff) | |
parent | 893e90c554c1ef85684b335655a5030d38a4a1b0 (diff) |
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
...
105 files changed, 1316 insertions, 644 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 90f9140eeefd..52930a20d8f8 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -55,11 +55,2 @@ 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 @@ -128,2 +119,3 @@ 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 @@ -152,2 +144,11 @@ 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 @@ -214,3 +215,3 @@ nouveau-y += core/engine/vp/nve0.o 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 @@ -226,5 +227,3 @@ 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 diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c index 295c22165eac..9079c0ac58e6 100644 --- a/drivers/gpu/drm/nouveau/core/core/client.c +++ b/drivers/gpu/drm/nouveau/core/core/client.c @@ -29,3 +29,3 @@ -#include <subdev/device.h> +#include <engine/device.h> @@ -60,4 +60,5 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg, 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; diff --git a/drivers/gpu/drm/nouveau/core/core/engine.c b/drivers/gpu/drm/nouveau/core/core/engine.c index 09b3bd502fd0..c8bed4a26833 100644 --- a/drivers/gpu/drm/nouveau/core/core/engine.c +++ b/drivers/gpu/drm/nouveau/core/core/engine.c @@ -35,3 +35,2 @@ nouveau_engine_create_(struct nouveau_object *parent, { - struct nouveau_device *device = nv_device(parent); struct nouveau_engine *engine; @@ -45,3 +44,4 @@ nouveau_engine_create_(struct nouveau_object *parent, - if (!nouveau_boolopt(device->cfgopt, iname, enable)) { + if ( parent && + !nouveau_boolopt(nv_device(parent)->cfgopt, iname, enable)) { if (!enable) diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index 6d01e0f0fc8a..7eb81c1b6fab 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c @@ -29,4 +29,6 @@ nouveau_event_put_locked(struct nouveau_event *event, int index, { - 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); @@ -55,4 +57,6 @@ nouveau_event_get(struct nouveau_event *event, int index, 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); + } } diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c index 3b2e7b6304d3..7f48e288215f 100644 --- a/drivers/gpu/drm/nouveau/core/core/object.c +++ b/drivers/gpu/drm/nouveau/core/core/object.c @@ -138,7 +138,7 @@ nouveau_object_ctor(struct nouveau_object *parent, 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) { @@ -149,4 +149,4 @@ nouveau_object_ctor(struct nouveau_object *parent, - if (*pobject) { - ofuncs->dtor(*pobject); + if (object) { + ofuncs->dtor(object); *pobject = NULL; @@ -157,3 +157,7 @@ nouveau_object_ctor(struct nouveau_object *parent, - nv_debug(*pobject, "created\n"); + if (ret == 0) { + nv_debug(object, "created\n"); + atomic_set(&object->refcount, 1); + } + return 0; @@ -329,2 +333,3 @@ nouveau_object_inc(struct nouveau_object *object) ret = nv_ofuncs(object)->init(object); + atomic_set(&object->usecount, 1); if (ret) { @@ -359,2 +364,3 @@ nouveau_object_decf(struct nouveau_object *object) ret = nv_ofuncs(object)->fini(object, false); + atomic_set(&object->usecount, 0); if (ret) @@ -383,2 +389,3 @@ nouveau_object_decs(struct nouveau_object *object) ret = nv_ofuncs(object)->fini(object, true); + atomic_set(&object->usecount, 0); if (ret) { diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c index db7c54943102..313380ce632d 100644 --- a/drivers/gpu/drm/nouveau/core/core/parent.c +++ b/drivers/gpu/drm/nouveau/core/core/parent.c @@ -26,2 +26,3 @@ #include <core/parent.h> +#include <core/client.h> @@ -52,3 +53,8 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle, - 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; diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index 3937ced5c753..86d24904e9d3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c @@ -31,3 +31,3 @@ -#include <subdev/device.h> +#include <engine/device.h> @@ -57,3 +57,2 @@ struct nouveau_devobj { struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; - bool created; }; @@ -240,3 +239,3 @@ 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))) @@ -244,18 +243,16 @@ nouveau_devobj_ctor(struct nouveau_object *parent, - 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 @@ -275,2 +272,6 @@ nouveau_devobj_ctor(struct nouveau_object *parent, return ret; + atomic_dec(&nv_object(device)->usecount); + } else + if (subdev) { + nouveau_subdev_reset(subdev); } @@ -294,70 +295,2 @@ nouveau_devobj_dtor(struct nouveau_object *object) -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 @@ -402,4 +335,4 @@ nouveau_devobj_ofuncs = { .dtor = nouveau_devobj_dtor, - .init = nouveau_devobj_init, - .fini = nouveau_devobj_fini, + .init = _nouveau_parent_init, + .fini = _nouveau_parent_fini, .rd08 = nouveau_devobj_rd08, @@ -415,3 +348,3 @@ nouveau_devobj_ofuncs = { *****************************************************************************/ -struct nouveau_oclass +static struct nouveau_oclass nouveau_device_sclass[] = { @@ -421,2 +354,66 @@ nouveau_device_sclass[] = { +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 @@ -430,6 +427,6 @@ nouveau_device_dtor(struct nouveau_object *object) - 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); } @@ -438,5 +435,7 @@ 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, }, @@ -458,3 +457,3 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname, - ret = nouveau_subdev_create_(NULL, NULL, &nouveau_device_oclass, 0, + ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true, "DEVICE", "device", length, pobject); @@ -464,3 +463,2 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname, - atomic_set(&nv_object(device)->usecount, 2); device->pdev = pdev; @@ -472,2 +470,3 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname, nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE"); + nv_engine(device)->sclass = nouveau_device_sclass; list_add(&device->head, &nv_devices); diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c index 473c5c03d3c9..a0284cf09c0f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -36,2 +35,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c index d0774f5bebe1..1b7809a095c3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -37,2 +36,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c index ab920e0dc45b..12a4005fa619 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -38,2 +37,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c index 5f2110261b04..cef0f1ea4c21 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -37,2 +36,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index f3d55efe9ac9..1719cb0ee595 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -39,2 +38,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c index 5ed2fa51ddc2..5e8c3de75593 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -40,2 +39,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> @@ -85,3 +85,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -111,3 +111,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -137,3 +137,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -163,3 +163,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -189,3 +189,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -215,3 +215,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -241,3 +241,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -267,3 +267,3 @@ nv50_identify(struct nouveau_device *device) 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; @@ -293,3 +293,3 @@ nv50_identify(struct nouveau_device *device) 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; diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 4393eb4d6564..955af122c3a6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -42,2 +41,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> @@ -287,2 +287,30 @@ nvc0_identify(struct nouveau_device *device) 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: diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 5c12391619fd..e6a77944f43b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -24,3 +24,2 @@ -#include <subdev/device.h> #include <subdev/bios.h> @@ -42,2 +41,3 @@ +#include <engine/device.h> #include <engine/dmaobj.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c index fa27b02ff829..31cc8fe8e7f0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c @@ -193,3 +193,3 @@ 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; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 02e369f80449..6a38402fa56c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -574,3 +574,4 @@ nv50_disp_base_ctor(struct nouveau_object *parent, 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); } @@ -721,3 +722,3 @@ nv50_disp_data_ctor(struct nouveau_object *parent, *pobject = parent; - return 0; + return 1; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 788dd34ccb54..019eacd8a68f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -475,3 +475,4 @@ nvd0_disp_base_ctor(struct nouveau_object *parent, - return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht); + return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0, + &base->ramht); } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index 7341ebe131fa..d3ec436d9cb5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -93,2 +93,4 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, + nouveau_event_trigger(priv->cevent, 0); + chan->size = size; @@ -169,2 +171,3 @@ nouveau_fifo_destroy(struct nouveau_fifo *priv) nouveau_event_destroy(&priv->uevent); + nouveau_event_destroy(&priv->cevent); nouveau_engine_destroy(&priv->base); @@ -193,2 +196,6 @@ nouveau_fifo_create_(struct nouveau_object *parent, + ret = nouveau_event_create(1, &priv->cevent); + if (ret) + return ret; + ret = nouveau_event_create(1, &priv->uevent); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index 840af6172788..ddaeb5572903 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -212,3 +212,4 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent, - 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) @@ -265,3 +266,4 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent, - 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) @@ -375,4 +377,4 @@ nv50_fifo_context_ctor(struct nouveau_object *parent, - 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) @@ -380,3 +382,3 @@ nv50_fifo_context_ctor(struct nouveau_object *parent, - 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); @@ -385,3 +387,3 @@ nv50_fifo_context_ctor(struct nouveau_object *parent, - 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); @@ -439,3 +441,3 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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]); @@ -444,3 +446,3 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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]); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index 094000e87871..35b94bd18808 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -182,3 +182,4 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent, - 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) @@ -244,3 +245,4 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent, - 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) @@ -338,3 +340,3 @@ nv84_fifo_context_ctor(struct nouveau_object *parent, - 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); @@ -343,3 +345,3 @@ nv84_fifo_context_ctor(struct nouveau_object *parent, - 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); @@ -352,4 +354,4 @@ nv84_fifo_context_ctor(struct nouveau_object *parent, - 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) @@ -357,4 +359,4 @@ nv84_fifo_context_ctor(struct nouveau_object *parent, - 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) @@ -409,3 +411,3 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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]); @@ -414,3 +416,3 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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]); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 4f226afb5591..4d4a6b905370 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -294,3 +294,4 @@ nvc0_fifo_context_ctor(struct nouveau_object *parent, - 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) @@ -625,3 +626,3 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0, &priv->playlist[0]); @@ -630,3 +631,3 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0, &priv->playlist[1]); @@ -635,3 +636,3 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 4419e40d88e9..9151919fb831 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -98,3 +98,3 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) 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); @@ -335,3 +335,4 @@ nve0_fifo_context_ctor(struct nouveau_object *parent, - 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) @@ -597,3 +598,3 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c index 0b7951a85943..4cc6269d4077 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c @@ -38,3 +38,2 @@ 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; @@ -46,3 +45,3 @@ nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) */ - ret = nouveau_gpuobj_new(parent, NULL, size, 0x1000, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, size, 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &info->chan); @@ -1401,3 +1400,3 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv) - 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); @@ -1417,3 +1416,3 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv) 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); @@ -1617,3 +1616,3 @@ 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); @@ -1660,6 +1659,6 @@ nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv) 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); @@ -1703,3 +1702,3 @@ nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x408804, 0x00000040); - if (chipset == 0xd9) { + if (chipset >= 0xd0) { nv_wr32(priv, 0x408808, 0x1043e005); @@ -1737,3 +1736,3 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) 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); @@ -1752,5 +1751,5 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) 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); @@ -1759,3 +1758,3 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x418828, 0x00008442); - if (chipset == 0xc1 || chipset == 0xd9) + if (chipset == 0xc1 || chipset >= 0xd0) nv_wr32(priv, 0x418830, 0x10000001); @@ -1770,3 +1769,3 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x4188f8, 0x00000000); - if (chipset == 0xd9) + if (chipset >= 0xd0) nv_wr32(priv, 0x4188fc, 0x20100008); @@ -1789,3 +1788,3 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) } - nv_wr32(priv, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006); + nv_wr32(priv, 0x418b00, chipset < 0xd0 ? 0x00000000 : 0x00000006); nv_wr32(priv, 0x418b08, 0x0a418820); @@ -1806,3 +1805,3 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x418c2c, 0x00000000); - if (chipset == 0xc1 || chipset == 0xd9) + if (chipset == 0xc1 || chipset >= 0xd0) nv_wr32(priv, 0x418c6c, 0x00000001); @@ -1825,3 +1824,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x419848, 0x00000000); - if (chipset == 0xc1 || chipset == 0xd9) + if (chipset == 0xc1 || chipset >= 0xd0) nv_wr32(priv, 0x419864, 0x00000129); @@ -1838,3 +1837,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x419a20, 0x00000800); - if (chipset == 0xd9) + if (chipset >= 0xd0) nv_wr32(priv, 0x00419ac4, 0x0017f440); @@ -1849,3 +1848,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x419bd0, 0x00900103); - if (chipset == 0xc1 || chipset == 0xd9) + if (chipset == 0xc1 || chipset >= 0xd0) nv_wr32(priv, 0x419be0, 0x00400001); @@ -1854,3 +1853,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) 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); @@ -1858,3 +1857,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x419c20, 0x00000000); - if (nv_device(priv)->chipset == 0xd9) { + if (nv_device(priv)->chipset >= 0xd0) { nv_wr32(priv, 0x419c24, 0x00084210); @@ -1870,3 +1869,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x419cf4, 0x00000183); - if (chipset == 0xc1 || chipset == 0xd9) + if (chipset == 0xc1 || chipset >= 0xd0) nv_wr32(priv, 0x419d20, 0x12180000); @@ -1875,3 +1874,3 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x419d24, 0x00001fff); - if (chipset == 0xc1 || chipset == 0xd9) + if (chipset == 0xc1 || chipset >= 0xd0) nv_wr32(priv, 0x419d44, 0x02180218); @@ -2212,3 +2211,3 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv) nv_icmd(priv, 0x00000217, 0x00000040); - if (nv_device(priv)->chipset == 0xd9) { + if (nv_device(priv)->chipset >= 0xd0) { for (i = 0x0400; i <= 0x0417; i++) @@ -2224,3 +2223,3 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv) nv_icmd(priv, 0x0000021f, 0x0000c080); - if (nv_device(priv)->chipset == 0xd9) { + if (nv_device(priv)->chipset >= 0xd0) { for (i = 0x0440; i <= 0x0457; i++) @@ -2791,3 +2790,3 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv) if (nv_device(priv)->chipset == 0xc1 || - nv_device(priv)->chipset == 0xd9) + nv_device(priv)->chipset >= 0xd0) nv_icmd(priv, 0x0000057b, 0x00000059); @@ -2893,3 +2892,3 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv) nv_icmd(priv, 0x0000095f, 0x00000020); - if (nv_device(priv)->chipset == 0xd9) + if (nv_device(priv)->chipset >= 0xd0) nv_icmd(priv, 0x0000097d, 0x00000020); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c index 6d8c63931ee6..ae27dae3fe38 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c @@ -2774,6 +2774,11 @@ nve0_grctx_generate(struct nvc0_graph_priv *priv) - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc index b86cc60dcd56..f7055af0f2a6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc @@ -89,2 +89,7 @@ chipsets: .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 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc index 0bcfa4d447e5..7fbdebb2bafb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc @@ -64,2 +64,5 @@ chipsets: .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 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c index 0607b9801748..b24559315903 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c @@ -256,3 +256,3 @@ nv20_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c index b2b650dd8b28..7a80d005a974 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c @@ -144,3 +144,3 @@ nv25_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c index 700462fa0ae0..3e1f32ee43d4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c @@ -111,3 +111,3 @@ nv2a_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c index cedadaa92d3f..e451db32e92a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c @@ -145,3 +145,3 @@ nv30_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c index 273f6320027b..9385ac7b44a4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c @@ -145,3 +145,3 @@ nv34_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c index f40ee2116ee1..9ce84b73f86a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c @@ -143,3 +143,3 @@ nv35_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 17049d5c723d..193a5de1b482 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -48,2 +48,10 @@ struct nv40_graph_chan { +static u64 +nv40_graph_units(struct nouveau_graph *graph) +{ + struct nv40_graph_priv *priv = (void *)graph; + + return nv_rd32(priv, 0x1540); +} + /******************************************************************************* @@ -361,2 +369,4 @@ nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->tile_prog = nv40_graph_tile_prog; + + priv->base.units = nv40_graph_units; return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index f2b1a7a124f2..1ac36110ca19 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c @@ -50,2 +50,10 @@ struct nv50_graph_chan { +static u64 +nv50_graph_units(struct nouveau_graph *graph) +{ + struct nv50_graph_priv *priv = (void *)graph; + + return nv_rd32(priv, 0x1540); +} + /******************************************************************************* @@ -821,2 +829,4 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + priv->base.units = nv50_graph_units; + switch (nv_device(priv)->chipset) { diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 0de0dd724aff..f9b9d82c287f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -62,2 +62,15 @@ 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; +} + /******************************************************************************* @@ -91,3 +104,4 @@ nvc0_graph_context_ctor(struct nouveau_object *parent, */ - 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) @@ -103,4 +117,4 @@ nvc0_graph_context_ctor(struct nouveau_object *parent, 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) @@ -520,5 +534,6 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 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); @@ -531,2 +546,4 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + priv->base.units = nvc0_graph_units; + if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { @@ -553,3 +570,4 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) @@ -557,3 +575,4 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h index a1e78de46456..c870dad0f670 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h @@ -120,2 +120,3 @@ nvc0_graph_class(void *obj) case 0xd9: + case 0xd7: return 0x9297; @@ -171,2 +172,4 @@ void nvc0_graph_context_dtor(struct nouveau_object *); +u64 nvc0_graph_units(struct nouveau_graph *); + #endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index 4857f913efdd..678c16f63055 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c @@ -79,2 +79,197 @@ nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) +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 @@ -84,2 +279,3 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, u32 trap = nv_rd32(priv, 0x400108); + int i; int rop; @@ -104,2 +300,28 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, + 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) { @@ -219,2 +441,4 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + priv->base.units = nvc0_graph_units; + if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { @@ -229,3 +453,4 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) @@ -233,3 +458,4 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c index a523eaad47e3..d698e710ddd4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c @@ -96,2 +96,28 @@ nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd, +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 @@ -103,2 +129,5 @@ nvc0_software_omthds[] = { { 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 }, {} diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h index d351a4e5819c..05840f3eee98 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/device.h +++ b/drivers/gpu/drm/nouveau/core/include/core/device.h @@ -8,3 +8,3 @@ enum nv_subdev_type { - NVDEV_SUBDEV_DEVICE, + NVDEV_ENGINE_DEVICE, NVDEV_SUBDEV_VBIOS, @@ -59,3 +59,3 @@ enum nv_subdev_type { struct nouveau_device { - struct nouveau_subdev base; + struct nouveau_engine base; struct list_head head; @@ -101,3 +101,3 @@ nv_device(void *obj) 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", diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h index 31cd852c96df..9f5ea900ff00 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/parent.h +++ b/drivers/gpu/drm/nouveau/core/include/core/parent.h @@ -53,4 +53,4 @@ 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 diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/device.h b/drivers/gpu/drm/nouveau/core/include/engine/device.h index c9e4c4afa50e..b3dd2c4c2f1e 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/device.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/device.h @@ -20,3 +20,2 @@ int nve0_identify(struct nouveau_device *); -extern struct nouveau_oclass nouveau_device_sclass[]; struct nouveau_device *nouveau_device_find(u64 name); diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h index b46c197709f3..633c2f806482 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -67,3 +67,4 @@ struct nouveau_fifo { - struct nouveau_event *uevent; + struct nouveau_event *cevent; /* channel creation event */ + struct nouveau_event *uevent; /* async user trigger */ diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h index 6943b40d0817..5d392439f2ac 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/graph.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/graph.h @@ -28,2 +28,6 @@ struct nouveau_graph { struct nouveau_engine base; + + /* Returns chipset-specific counts of units packed into an u64. + */ + u64 (*units)(struct nouveau_graph *); }; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h index f351f63bc654..a1985ed3d58d 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h @@ -6,4 +6,11 @@ +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); }; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h index fded97cea500..d5502267c30f 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h @@ -23,14 +23,18 @@ 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)) - -#define _nouveau_mc_dtor _nouveau_subdev_dtor -#define _nouveau_mc_init _nouveau_subdev_init -#define _nouveau_mc_fini _nouveau_subdev_fini + 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)); \ +}) + +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); @@ -42,4 +46,2 @@ extern struct nouveau_oclass nvc0_mc_oclass; -void nouveau_mc_intr(struct nouveau_subdev *); - extern const struct nouveau_mc_intr nv04_mc_intr[]; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index 0b20fc0d19c1..c075998d82e6 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -75,2 +75,3 @@ 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; diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h index eb496033b55c..3bd9be2ab37f 100644 --- a/drivers/gpu/drm/nouveau/core/os.h +++ b/drivers/gpu/drm/nouveau/core/os.h @@ -19,2 +19,3 @@ #include <linux/reboot.h> +#include <linux/interrupt.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c index c3acf5b70d9e..649f1ced1fe0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c @@ -124,4 +124,4 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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); @@ -130,4 +130,5 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) @@ -135,3 +136,4 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) @@ -147,5 +149,5 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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; @@ -159,3 +161,3 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) @@ -184,3 +186,3 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c index 77a6fb725d3f..f8a44956dec1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c @@ -103,3 +103,4 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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; @@ -108,3 +109,4 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) @@ -116,3 +118,3 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_gpuobj_new(parent, NULL, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, (pci_resource_len(pdev, 3) >> 12) * 8, @@ -135,3 +137,4 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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; @@ -140,3 +143,4 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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) diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 9c41b58d57e2..c300b5e7b670 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -66,5 +66,7 @@ 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; @@ -75,5 +77,7 @@ 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; @@ -84,5 +88,7 @@ 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; @@ -94,12 +100,17 @@ 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; } @@ -229,3 +240,4 @@ init_i2c(struct nvbios_init *init, int index) if (!init->outp) { - error("script needs output for i2c\n"); + if (init_exec(init)) + error("script needs output for i2c\n"); return NULL; @@ -546,3 +558,4 @@ init_tmds_reg(struct nvbios_init *init, u8 tmds) - error("tmds opcodes need dcb\n"); + if (init_exec(init)) + error("tmds opcodes need dcb\n"); } else { @@ -794,3 +807,4 @@ init_dp_condition(struct nvbios_init *init) - warn("script needs dp output table data\n"); + if (init_exec(init)) + warn("script needs dp output table data\n"); break; @@ -818,3 +832,3 @@ init_io_mask_or(struct nvbios_init *init) - 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; @@ -837,3 +851,3 @@ init_io_or(struct nvbios_init *init) - 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; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index 7606ed15b6fa..86ad59203c8b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c @@ -25,2 +25,3 @@ #include <subdev/fb.h> +#include <subdev/ltcg.h> #include <subdev/bios.h> @@ -33,24 +34,4 @@ struct nvc0_fb_priv { -/* 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]; + @@ -60,3 +41,3 @@ 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)); } @@ -132,2 +113,3 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, int ret; + const bool comp = nvc0_pte_storage_type_map[type] != type; @@ -144,3 +126,2 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, INIT_LIST_HEAD(&mem->regions); - mem->memtype = type; mem->size = size; @@ -148,2 +129,15 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, 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 { @@ -170,2 +164,13 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, +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 @@ -180,3 +185,4 @@ nvc0_fb_init(struct nouveau_object *object) - nv_wr32(priv, 0x100c10, priv->r100c10 >> 8); + if (priv->r100c10_page) + nv_wr32(priv, 0x100c10, priv->r100c10 >> 8); return 0; @@ -216,12 +222,12 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 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; + } diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 2e98e8a3f1aa..8ae2625415e1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -142,8 +142,4 @@ 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; diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c index f5bbd3834116..795393d7b2f5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c @@ -95,3 +95,2 @@ nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent, struct nouveau_object *engine = nv_object(imem); - struct nv04_instmem_priv *priv = (void *)(imem); int ret; @@ -103,10 +102,2 @@ nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent, - /* 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; @@ -136,3 +127,4 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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) @@ -141,3 +133,3 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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) @@ -146,3 +138,3 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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); @@ -152,3 +144,4 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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) @@ -156,3 +149,2 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - priv->created = true; return 0; diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h index 7983d8d9b358..b15b61310236 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h @@ -11,3 +11,2 @@ struct nv04_instmem_priv { struct nouveau_instmem base; - bool created; diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c index da64253201ef..716bf41bc3c1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c @@ -84,3 +84,4 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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) @@ -89,3 +90,4 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* 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) @@ -96,3 +98,4 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, */ - 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) @@ -103,3 +106,3 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, */ - ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0, NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc); @@ -108,3 +111,2 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - priv->created = true; return 0; diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c index 078a2b9d6bd6..e4940fb166e8 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c @@ -25,2 +25,4 @@ #include <subdev/ltcg.h> +#include <subdev/fb.h> +#include <subdev/timer.h> @@ -28,3 +30,8 @@ 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; }; @@ -64,2 +71,94 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev) 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, @@ -69,2 +168,3 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvc0_ltcg_priv *priv; + struct nouveau_fb *pfb = nouveau_fb(parent); int ret; @@ -76,5 +176,17 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - 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; @@ -83,2 +195,15 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, +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 @@ -88,3 +213,3 @@ nvc0_ltcg_oclass = { .ctor = nvc0_ltcg_ctor, - .dtor = _nouveau_ltcg_dtor, + .dtor = nvc0_ltcg_dtor, .init = _nouveau_ltcg_init, diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c index 8379aafa6e1b..1c0330b8c9a4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c @@ -26,6 +26,6 @@ -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; @@ -37,3 +37,3 @@ nouveau_mc_intr(struct nouveau_subdev *subdev) if (stat & map->stat) { - unit = nouveau_subdev(subdev, map->unit); + unit = nouveau_subdev(pmc, map->unit); if (unit && unit->intr) @@ -48,2 +48,54 @@ nouveau_mc_intr(struct nouveau_subdev *subdev) } + + 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; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c index 89da8fa7ea0f..8c769715227b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c @@ -57,3 +57,2 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv04_mc_intr; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c index 397d868359ad..51919371810f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c @@ -43,3 +43,2 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv04_mc_intr; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index 5965add6daee..d796924f9930 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c @@ -59,3 +59,2 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv50_mc_intr; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c index 3a80b29dce0f..e82fd21b5041 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c @@ -61,3 +61,2 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nv98_mc_intr; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c index 42bbf72023a8..737bd4b682e1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c @@ -63,3 +63,2 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - nv_subdev(priv)->intr = nouveau_mc_intr; priv->base.intr_map = nvc0_mc_intr; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index a70d1b7e397b..002e51b3af93 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -167,3 +167,3 @@ nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) -static void +void nv40_therm_intr(struct nouveau_subdev *subdev) diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c index 86632cbd65ce..8cf7597a2182 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c @@ -120,141 +120,32 @@ nv50_fan_pwm_clock(struct nouveau_therm *therm) -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; - - 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_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) +nv50_sensor_setup(struct nouveau_therm *therm) { - 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); + nv_mask(therm, 0x20010, 0x40000000, 0x0); + mdelay(20); /* wait for the temperature to stabilize */ } -static void -nv50_therm_intr(struct nouveau_subdev *subdev) +static int +nv50_temp_get(struct nouveau_therm *therm) { - 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; - } + int core_temp; - /* 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; - } + core_temp = nv_rd32(therm, 0x20014) & 0x3fff; - /* THRS_2 : critical */ - if (intr & 0x010) { - nv50_therm_threshold_hyst_emulation(therm, 0x204c0, 22, - &sensor->thrs_critical, - NOUVEAU_THERM_THRS_CRITICAL); - intr &= ~0x010; - } + /* 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; - if (intr) - nv_error(therm, "unhandled intr 0x%08x\n", intr); + 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; - /* ACK everything */ - nv_wr32(therm, 0x20100, 0xffffffff); - nv_wr32(therm, 0x1100, 0x10000); /* PBUS */ + /* reserve negative temperatures for errors */ + if (core_temp < 0) + core_temp = 0; - spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); + return core_temp; } @@ -280,18 +171,4 @@ nv50_therm_ctor(struct nouveau_object *parent, 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; @@ -300,2 +177,12 @@ nv50_therm_ctor(struct nouveau_object *parent, +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 @@ -306,3 +193,3 @@ nv50_therm_oclass = { .dtor = _nouveau_therm_dtor, - .init = _nouveau_therm_init, + .init = nv50_therm_init, .fini = _nouveau_therm_fini, diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c new file mode 100644 index 000000000000..42ba633ccff7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c @@ -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, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c index 2dcc5437116a..d11a7c400813 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c @@ -83,3 +83,3 @@ nva3_therm_ctor(struct nouveau_object *parent, 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; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c index d7d30ee8332e..54c28bdc4204 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c @@ -137,3 +137,3 @@ nvd0_therm_ctor(struct nouveau_object *parent, 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; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 438d9824b774..15ca64e481f1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -136,2 +136,3 @@ 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); @@ -140,3 +141,3 @@ 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); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index 470f6a47b656..dde746c78c8a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -207,9 +207,9 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm) - 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); diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index 8e1bae4f12e8..9469b8275675 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -98,7 +98,12 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time, 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); diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c index 6adbbc9cc361..ed45437167f2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c @@ -112,3 +112,3 @@ nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_gpuobj_new(parent, NULL, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 + diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c index 9474cfca6e4c..064c76262876 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c @@ -121,3 +121,3 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_gpuobj_new(parent, NULL, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, (NV41_GART_SIZE / NV41_GART_PAGE) * 4, diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c index aa8131436e3d..fae1f67d5948 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c @@ -198,3 +198,3 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_gpuobj_new(parent, NULL, + ret = nouveau_gpuobj_new(nv_object(priv), NULL, (NV44_GART_SIZE / NV44_GART_PAGE) * 4, diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c index 30c61e6c2017..4c3b0a23b9d6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c @@ -30,2 +30,3 @@ #include <subdev/vm.h> +#include <subdev/ltcg.h> @@ -36,2 +37,43 @@ struct nvc0_vmmgr_priv { + +/* 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 @@ -70,3 +112,3 @@ nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, { - u32 next = 1 << (vma->node->type - 8); + u64 next = 1 << (vma->node->type - 8); @@ -74,2 +116,12 @@ nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 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--) { @@ -87,2 +139,4 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 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]; @@ -90,3 +144,3 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 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)); diff --git a/drivers/gpu/drm/nouveau/dispnv04/Makefile b/drivers/gpu/drm/nouveau/dispnv04/Makefile new file mode 100644 index 000000000000..ea3f5b8a0f95 --- /dev/null +++ b/drivers/gpu/drm/nouveau/dispnv04/Makefile @@ -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 diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c index 6da576445b3d..2e70462883e8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_calc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c @@ -27,3 +27,3 @@ #include "nouveau_reg.h" -#include "nouveau_hw.h" +#include "hw.h" diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 6578cd28c556..0782bd2f1e04 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -35,6 +35,6 @@ #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" @@ -1072,2 +1072 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) } - diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/dispnv04/cursor.c index fe86f0de348f..a810303169de 100644 --- a/drivers/gpu/drm/nouveau/nv04_cursor.c +++ b/drivers/gpu/drm/nouveau/dispnv04/cursor.c @@ -5,3 +5,3 @@ #include "nouveau_crtc.h" -#include "nouveau_hw.h" +#include "hw.h" @@ -70,2 +70 @@ nv04_cursor_init(struct nouveau_crtc *crtc) } - diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c index 64f7020fb605..434b920f6bd4 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c @@ -33,3 +33,3 @@ #include "nouveau_crtc.h" -#include "nouveau_hw.h" +#include "hw.h" #include "nvreg.h" diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index 7e24cdf1cb39..93dd23ff0093 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -34,3 +34,3 @@ #include "nouveau_crtc.h" -#include "nouveau_hw.h" +#include "hw.h" #include "nvreg.h" diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index ad48444c385c..4908d3fd0486 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -32,3 +32,3 @@ #include "nouveau_reg.h" -#include "nouveau_hw.h" +#include "hw.h" #include "nouveau_encoder.h" diff --git a/drivers/gpu/drm/nouveau/nv04_display.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h index a0a031dad13f..a0a031dad13f 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.h +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c index 617a06ffdb46..973056b86207 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -26,3 +26,3 @@ #include "nouveau_drm.h" -#include "nouveau_hw.h" +#include "hw.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/dispnv04/hw.h index 7dff1021fab4..eeb70d912d99 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.h +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.h @@ -26,3 +26,4 @@ #include <drm/drmP.h> -#include "nv04_display.h" +#include "disp.h" +#include "nvreg.h" diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/dispnv04/nvreg.h index bbfb1a68fb11..bbfb1a68fb11 100644 --- a/drivers/gpu/drm/nouveau/nvreg.h +++ b/drivers/gpu/drm/nouveau/dispnv04/nvreg.h diff --git a/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c index 1cdfe2a5875d..08c6f5e50610 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv_modes.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c @@ -31,4 +31,4 @@ #include "nouveau_crtc.h" -#include "nouveau_hw.h" -#include "nv17_tv.h" +#include "hw.h" +#include "tvnv17.h" diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index 4a69ccdef9b4..bf13db4e8631 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c @@ -32,3 +32,3 @@ #include "nouveau_crtc.h" -#include "nouveau_hw.h" +#include "hw.h" #include <drm/drm_crtc_helper.h> diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index 977e42be2050..acef48f4a4ea 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -33,4 +33,4 @@ #include "nouveau_crtc.h" -#include "nouveau_hw.h" -#include "nv17_tv.h" +#include "hw.h" +#include "tvnv17.h" diff --git a/drivers/gpu/drm/nouveau/nv17_tv.h b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h index 7b331543a41b..7b331543a41b 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.h +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 5eb3e0da7c6e..1c4c6c9161ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -32,2 +32,3 @@ #include <subdev/instmem.h> +#include <engine/graph.h> @@ -170,2 +171,3 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) struct nouveau_timer *ptimer = nouveau_timer(device); + struct nouveau_graph *graph = (void *)nouveau_engine(device, NVDEV_ENGINE_GR); struct drm_nouveau_getparam *getparam = data; @@ -210,10 +212,4 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) 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: diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 5d940302d2aa..2ffad2176b7f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -241,2 +241,5 @@ nouveau_backlight_init(struct drm_device *dev) case NV_50: + case NV_C0: + case NV_D0: + case NV_E0: return nv50_backlight_init(connector); diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 50a6dd02f7c5..6aa2137e093a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -30,3 +30,3 @@ #include "nouveau_reg.h" -#include "nouveau_hw.h" +#include "dispnv04/hw.h" #include "nouveau_encoder.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 7ccd28f11adf..0067586eb015 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -26,4 +26,2 @@ -#include "nvreg.h" - #define DCB_MAX_NUM_ENTRIES 16 diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 4dd7ae2ac6c6..4da776f344d7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -34,3 +34,3 @@ #include "nouveau_drm.h" -#include "nouveau_hw.h" +#include "dispnv04/hw.h" #include "nouveau_acpi.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 4610c3a29bbe..7bf22d4a3d96 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -30,3 +30,3 @@ #include "nouveau_fbcon.h" -#include "nouveau_hw.h" +#include "dispnv04/hw.h" #include "nouveau_crtc.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index c95decf543e9..c33b13fb18db 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -33,9 +33,8 @@ -#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" @@ -367,6 +366,2 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) - ret = nouveau_irq_init(dev); - if (ret) - goto fail_irq; - ret = nouveau_display_create(dev); @@ -390,4 +385,2 @@ fail_dispinit: fail_dispctor: - nouveau_irq_fini(dev); -fail_irq: nouveau_bios_takedown(dev); @@ -417,3 +410,2 @@ nouveau_drm_unload(struct drm_device *dev) - nouveau_irq_fini(dev); nouveau_bios_takedown(dev); @@ -535,3 +527,2 @@ nouveau_do_resume(struct drm_device *dev) nouveau_run_vbios_init(dev); - nouveau_irq_postinstall(dev); nouveau_pm_resume(dev); @@ -671,4 +662,3 @@ driver = { 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, @@ -686,7 +676,2 @@ driver = { - .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, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 9c39bafbef2c..f2b30f89dee0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -12,3 +12,14 @@ #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). + */ diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index e24341229d5e..24660c0f713d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -32,3 +32,3 @@ #include <drm/drm_encoder_slave.h> -#include "nv04_display.h" +#include "dispnv04/disp.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c deleted file mode 100644 index 1303680affd3..000000000000 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ /dev/null @@ -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); -} diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.h b/drivers/gpu/drm/nouveau/nouveau_irq.h deleted file mode 100644 index 06714ad857bb..000000000000 --- a/drivers/gpu/drm/nouveau/nouveau_irq.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NOUVEAU_IRQ_H__ -#define __NOUVEAU_IRQ_H__ - -extern int nouveau_irq_init(struct drm_device *); -extern void nouveau_irq_fini(struct drm_device *); -extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); -extern void nouveau_irq_preinstall(struct drm_device *); -extern int nouveau_irq_postinstall(struct drm_device *); -extern void nouveau_irq_uninstall(struct drm_device *); - -#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 9be9cb58e19b..f19a15a3bc03 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -37,3 +37,5 @@ nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) { - /* nothing to do */ + struct nouveau_drm *drm = nouveau_bdev(man->bdev); + struct nouveau_fb *pfb = nouveau_fb(drm->device); + man->priv = pfb; return 0; @@ -44,3 +46,3 @@ nouveau_vram_manager_fini(struct ttm_mem_type_manager *man) { - /* nothing to do */ + man->priv = NULL; return 0; @@ -106,3 +108,4 @@ nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) { - struct nouveau_mm *mm = man->priv; + struct nouveau_fb *pfb = man->priv; + struct nouveau_mm *mm = &pfb->vram; struct nouveau_mm_node *r; @@ -163,2 +166,4 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, { + struct nouveau_drm *drm = nouveau_bdev(bo->bdev); + struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_mem *node; @@ -173,2 +178,16 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, + switch (nv_device(drm->device)->card_type) { + case NV_50: + if (nv_device(drm->device)->chipset != 0x50) + node->memtype = (nvbo->tile_flags & 0x7f00) >> 8; + break; + case NV_C0: + case NV_D0: + case NV_E0: + node->memtype = (nvbo->tile_flags & 0xff00) >> 8; + break; + default: + break; + } + mem->mm_node = node; diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c index 2a0cc9d0614a..27afc0ea28b0 100644 --- a/drivers/gpu/drm/nouveau/nv04_pm.c +++ b/drivers/gpu/drm/nouveau/nv04_pm.c @@ -27,3 +27,3 @@ #include "nouveau_reg.h" -#include "nouveau_hw.h" +#include "dispnv04/hw.h" #include "nouveau_pm.h" diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c index 3382064c7f33..3af5bcd0b203 100644 --- a/drivers/gpu/drm/nouveau/nv40_pm.c +++ b/drivers/gpu/drm/nouveau/nv40_pm.c @@ -28,3 +28,3 @@ #include "nouveau_pm.h" -#include "nouveau_hw.h" +#include "dispnv04/hw.h" diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c index 8bd5d2781baf..69620e39c90c 100644 --- a/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/drivers/gpu/drm/nouveau/nv50_pm.c @@ -27,3 +27,3 @@ #include "nouveau_bios.h" -#include "nouveau_hw.h" +#include "dispnv04/hw.h" #include "nouveau_pm.h" |