diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine')
108 files changed, 3598 insertions, 2094 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c index f31527733e00..abb410ef09ea 100644 --- a/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/copy/nva3.c @@ -30,7 +30,6 @@ #include <subdev/vm.h> #include <core/client.h> -#include <core/class.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c index ac3291f781f6..9261694d0d35 100644 --- a/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/copy/nvc0.c @@ -26,9 +26,7 @@ #include <engine/fifo.h> #include <engine/copy.h> -#include <core/class.h> #include <core/enum.h> -#include <core/class.h> #include <core/enum.h> #include "fuc/nvc0.fuc.h" diff --git a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c index 748a61eb3c6f..c7194b354605 100644 --- a/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/copy/nve0.c @@ -24,7 +24,6 @@ #include <core/os.h> #include <core/enum.h> -#include <core/class.h> #include <core/engctx.h> #include <engine/copy.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c index 2551dafbec73..ea5c42f31791 100644 --- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv84.c @@ -25,7 +25,6 @@ #include <core/client.h> #include <core/os.h> #include <core/enum.h> -#include <core/class.h> #include <core/engctx.h> #include <core/gpuobj.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c index c7082377ec76..5571c09534cb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c +++ b/drivers/gpu/drm/nouveau/core/engine/crypt/nv98.c @@ -25,7 +25,6 @@ #include <core/client.h> #include <core/os.h> #include <core/enum.h> -#include <core/class.h> #include <core/engctx.h> #include <subdev/timer.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/device/acpi.c b/drivers/gpu/drm/nouveau/core/engine/device/acpi.c new file mode 100644 index 000000000000..4dbf0ba89e5c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/acpi.c @@ -0,0 +1,59 @@ +/* + * Copyright 2014 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "acpi.h" + +#ifdef CONFIG_ACPI +static int +nvkm_acpi_ntfy(struct notifier_block *nb, unsigned long val, void *data) +{ + struct nouveau_device *device = + container_of(nb, typeof(*device), acpi.nb); + struct acpi_bus_event *info = data; + + if (!strcmp(info->device_class, "ac_adapter")) + nvkm_event_send(&device->event, 1, 0, NULL, 0); + + return NOTIFY_DONE; +} +#endif + +int +nvkm_acpi_fini(struct nouveau_device *device, bool suspend) +{ +#ifdef CONFIG_ACPI + unregister_acpi_notifier(&device->acpi.nb); +#endif + return 0; +} + +int +nvkm_acpi_init(struct nouveau_device *device) +{ +#ifdef CONFIG_ACPI + device->acpi.nb.notifier_call = nvkm_acpi_ntfy; + register_acpi_notifier(&device->acpi.nb); +#endif + return 0; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/device/acpi.h b/drivers/gpu/drm/nouveau/core/engine/device/acpi.h new file mode 100644 index 000000000000..cc49f4f568cd --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/acpi.h @@ -0,0 +1,9 @@ +#ifndef __NVKM_DEVICE_ACPI_H__ +#define __NVKM_DEVICE_ACPI_H__ + +#include <engine/device.h> + +int nvkm_acpi_init(struct nouveau_device *); +int nvkm_acpi_fini(struct nouveau_device *, bool); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index 18c8c7245b73..8928f7981d4a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c @@ -26,10 +26,14 @@ #include <core/device.h> #include <core/client.h> #include <core/option.h> +#include <nvif/unpack.h> +#include <nvif/class.h> -#include <core/class.h> +#include <subdev/fb.h> +#include <subdev/instmem.h> #include "priv.h" +#include "acpi.h" static DEFINE_MUTEX(nv_devices_mutex); static LIST_HEAD(nv_devices); @@ -49,74 +53,258 @@ nouveau_device_find(u64 name) return match; } +int +nouveau_device_list(u64 *name, int size) +{ + struct nouveau_device *device; + int nr = 0; + mutex_lock(&nv_devices_mutex); + list_for_each_entry(device, &nv_devices, head) { + if (nr++ < size) + name[nr - 1] = device->handle; + } + mutex_unlock(&nv_devices_mutex); + return nr; +} + /****************************************************************************** * nouveau_devobj (0x0080): class implementation *****************************************************************************/ + struct nouveau_devobj { struct nouveau_parent base; struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; }; +static int +nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size) +{ + struct nouveau_device *device = nv_device(object); + struct nouveau_fb *pfb = nouveau_fb(device); + struct nouveau_instmem *imem = nouveau_instmem(device); + union { + struct nv_device_info_v0 v0; + } *args = data; + int ret; + + nv_ioctl(object, "device info size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "device info vers %d\n", args->v0.version); + } else + return ret; + + switch (device->chipset) { + case 0x01a: + case 0x01f: + case 0x04c: + case 0x04e: + case 0x063: + case 0x067: + case 0x068: + case 0x0aa: + case 0x0ac: + case 0x0af: + args->v0.platform = NV_DEVICE_INFO_V0_IGP; + break; + default: + if (device->pdev) { + if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP)) + args->v0.platform = NV_DEVICE_INFO_V0_AGP; + else + if (pci_is_pcie(device->pdev)) + args->v0.platform = NV_DEVICE_INFO_V0_PCIE; + else + args->v0.platform = NV_DEVICE_INFO_V0_PCI; + } else { + args->v0.platform = NV_DEVICE_INFO_V0_SOC; + } + break; + } + + switch (device->card_type) { + case NV_04: args->v0.family = NV_DEVICE_INFO_V0_TNT; break; + case NV_10: + case NV_11: args->v0.family = NV_DEVICE_INFO_V0_CELSIUS; break; + case NV_20: args->v0.family = NV_DEVICE_INFO_V0_KELVIN; break; + case NV_30: args->v0.family = NV_DEVICE_INFO_V0_RANKINE; break; + case NV_40: args->v0.family = NV_DEVICE_INFO_V0_CURIE; break; + case NV_50: args->v0.family = NV_DEVICE_INFO_V0_TESLA; break; + case NV_C0: args->v0.family = NV_DEVICE_INFO_V0_FERMI; break; + case NV_E0: args->v0.family = NV_DEVICE_INFO_V0_KEPLER; break; + case GM100: args->v0.family = NV_DEVICE_INFO_V0_MAXWELL; break; + default: + args->v0.family = 0; + break; + } + + args->v0.chipset = device->chipset; + args->v0.revision = device->chipset >= 0x10 ? nv_rd32(device, 0) : 0x00; + if (pfb) args->v0.ram_size = args->v0.ram_user = pfb->ram->size; + else args->v0.ram_size = args->v0.ram_user = 0; + if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved; + return 0; +} + +static int +nouveau_devobj_mthd(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + switch (mthd) { + case NV_DEVICE_V0_INFO: + return nouveau_devobj_info(object, data, size); + default: + break; + } + return -EINVAL; +} + +static u8 +nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) +{ + return nv_rd08(object->engine, addr); +} + +static u16 +nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) +{ + return nv_rd16(object->engine, addr); +} + +static u32 +nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) +{ + return nv_rd32(object->engine, addr); +} + +static void +nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) +{ + nv_wr08(object->engine, addr, data); +} + +static void +nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) +{ + nv_wr16(object->engine, addr, data); +} + +static void +nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) +{ + nv_wr32(object->engine, addr, data); +} + +static int +nouveau_devobj_map(struct nouveau_object *object, u64 *addr, u32 *size) +{ + struct nouveau_device *device = nv_device(object); + *addr = nv_device_resource_start(device, 0); + *size = nv_device_resource_len(device, 0); + return 0; +} + static const u64 disable_map[] = { - [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_DISABLE_VBIOS, - [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_GPIO] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_I2C] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_MXM] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_MC] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_BUS] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_TIMER] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_FB] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_LTCG] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_IBUS] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_VM] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE, - [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE, - [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE, - [NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE, - [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO, - [NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO, - [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH, - [NVDEV_ENGINE_MPEG] = NV_DEVICE_DISABLE_MPEG, - [NVDEV_ENGINE_ME] = NV_DEVICE_DISABLE_ME, - [NVDEV_ENGINE_VP] = NV_DEVICE_DISABLE_VP, - [NVDEV_ENGINE_CRYPT] = NV_DEVICE_DISABLE_CRYPT, - [NVDEV_ENGINE_BSP] = NV_DEVICE_DISABLE_BSP, - [NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP, - [NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0, - [NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1, - [NVDEV_ENGINE_VIC] = NV_DEVICE_DISABLE_VIC, - [NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC, - [NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP, + [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_V0_DISABLE_VBIOS, + [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_GPIO] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_I2C] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_MXM] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_MC] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_BUS] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_TIMER] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_FB] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_LTC] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_IBUS] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_VM] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_BAR] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_VOLT] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_THERM] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_SUBDEV_PWR] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_ENGINE_PERFMON] = NV_DEVICE_V0_DISABLE_CORE, + [NVDEV_ENGINE_FIFO] = NV_DEVICE_V0_DISABLE_FIFO, + [NVDEV_ENGINE_SW] = NV_DEVICE_V0_DISABLE_FIFO, + [NVDEV_ENGINE_GR] = NV_DEVICE_V0_DISABLE_GRAPH, + [NVDEV_ENGINE_MPEG] = NV_DEVICE_V0_DISABLE_MPEG, + [NVDEV_ENGINE_ME] = NV_DEVICE_V0_DISABLE_ME, + [NVDEV_ENGINE_VP] = NV_DEVICE_V0_DISABLE_VP, + [NVDEV_ENGINE_CRYPT] = NV_DEVICE_V0_DISABLE_CRYPT, + [NVDEV_ENGINE_BSP] = NV_DEVICE_V0_DISABLE_BSP, + [NVDEV_ENGINE_PPP] = NV_DEVICE_V0_DISABLE_PPP, + [NVDEV_ENGINE_COPY0] = NV_DEVICE_V0_DISABLE_COPY0, + [NVDEV_ENGINE_COPY1] = NV_DEVICE_V0_DISABLE_COPY1, + [NVDEV_ENGINE_VIC] = NV_DEVICE_V0_DISABLE_VIC, + [NVDEV_ENGINE_VENC] = NV_DEVICE_V0_DISABLE_VENC, + [NVDEV_ENGINE_DISP] = NV_DEVICE_V0_DISABLE_DISP, [NVDEV_SUBDEV_NR] = 0, }; +static void +nouveau_devobj_dtor(struct nouveau_object *object) +{ + struct nouveau_devobj *devobj = (void *)object; + int i; + + for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) + nouveau_object_ref(NULL, &devobj->subdev[i]); + + nouveau_parent_destroy(&devobj->base); +} + +static struct nouveau_oclass +nouveau_devobj_oclass_super = { + .handle = NV_DEVICE, + .ofuncs = &(struct nouveau_ofuncs) { + .dtor = nouveau_devobj_dtor, + .init = _nouveau_parent_init, + .fini = _nouveau_parent_fini, + .mthd = nouveau_devobj_mthd, + .map = nouveau_devobj_map, + .rd08 = nouveau_devobj_rd08, + .rd16 = nouveau_devobj_rd16, + .rd32 = nouveau_devobj_rd32, + .wr08 = nouveau_devobj_wr08, + .wr16 = nouveau_devobj_wr16, + .wr32 = nouveau_devobj_wr32, + } +}; + static int nouveau_devobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv_device_v0 v0; + } *args = data; struct nouveau_client *client = nv_client(parent); struct nouveau_device *device; struct nouveau_devobj *devobj; - struct nv_device_class *args = data; u32 boot0, strap; u64 disable, mmio_base, mmio_size; void __iomem *map; int ret, i, c; - if (size < sizeof(struct nv_device_class)) - return -EINVAL; + nv_ioctl(parent, "create device size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create device v%d device %016llx " + "disable %016llx debug0 %016llx\n", + args->v0.version, args->v0.device, + args->v0.disable, args->v0.debug0); + } else + return ret; + + /* give priviledged clients register access */ + if (client->super) + oclass = &nouveau_devobj_oclass_super; /* find the device subdev that matches what the client requested */ device = nv_device(client->device); - if (args->device != ~0) { - device = nouveau_device_find(args->device); + if (args->v0.device != ~0) { + device = nouveau_device_find(args->v0.device); if (!device) return -ENODEV; } @@ -135,14 +323,14 @@ nouveau_devobj_ctor(struct nouveau_object *parent, mmio_size = nv_device_resource_len(device, 0); /* translate api disable mask into internal mapping */ - disable = args->debug0; + disable = args->v0.debug0; for (i = 0; i < NVDEV_SUBDEV_NR; i++) { - if (args->disable & disable_map[i]) + if (args->v0.disable & disable_map[i]) disable |= (1ULL << i); } /* identify the chipset, and determine classes of subdev/engines */ - if (!(args->disable & NV_DEVICE_DISABLE_IDENTIFY) && + if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY) && !device->card_type) { map = ioremap(mmio_base, 0x102000); if (map == NULL) @@ -180,8 +368,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, case 0x080: case 0x090: case 0x0a0: device->card_type = NV_50; break; - case 0x0c0: device->card_type = NV_C0; break; - case 0x0d0: device->card_type = NV_D0; break; + case 0x0c0: + case 0x0d0: device->card_type = NV_C0; break; case 0x0e0: case 0x0f0: case 0x100: device->card_type = NV_E0; break; @@ -206,8 +394,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent, case NV_30: ret = nv30_identify(device); break; case NV_40: ret = nv40_identify(device); break; case NV_50: ret = nv50_identify(device); break; - case NV_C0: - case NV_D0: ret = nvc0_identify(device); break; + case NV_C0: ret = nvc0_identify(device); break; case NV_E0: ret = nve0_identify(device); break; case GM100: ret = gm100_identify(device); break; default: @@ -242,7 +429,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent, nv_debug(device, "crystal freq: %dKHz\n", device->crystal); } - if (!(args->disable & NV_DEVICE_DISABLE_MMIO) && + if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) && !nv_subdev(device)->mmio) { nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size); if (!nv_subdev(device)->mmio) { @@ -298,71 +485,19 @@ nouveau_devobj_ctor(struct nouveau_object *parent, return 0; } -static void -nouveau_devobj_dtor(struct nouveau_object *object) -{ - struct nouveau_devobj *devobj = (void *)object; - int i; - - for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) - nouveau_object_ref(NULL, &devobj->subdev[i]); - - nouveau_parent_destroy(&devobj->base); -} - -static u8 -nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) -{ - return nv_rd08(object->engine, addr); -} - -static u16 -nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) -{ - return nv_rd16(object->engine, addr); -} - -static u32 -nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) -{ - return nv_rd32(object->engine, addr); -} - -static void -nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) -{ - nv_wr08(object->engine, addr, data); -} - -static void -nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) -{ - nv_wr16(object->engine, addr, data); -} - -static void -nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) -{ - nv_wr32(object->engine, addr, data); -} - static struct nouveau_ofuncs nouveau_devobj_ofuncs = { .ctor = nouveau_devobj_ctor, .dtor = nouveau_devobj_dtor, .init = _nouveau_parent_init, .fini = _nouveau_parent_fini, - .rd08 = nouveau_devobj_rd08, - .rd16 = nouveau_devobj_rd16, - .rd32 = nouveau_devobj_rd32, - .wr08 = nouveau_devobj_wr08, - .wr16 = nouveau_devobj_wr16, - .wr32 = nouveau_devobj_wr32, + .mthd = nouveau_devobj_mthd, }; /****************************************************************************** * nouveau_device: engine functions *****************************************************************************/ + static struct nouveau_oclass nouveau_device_sclass[] = { { 0x0080, &nouveau_devobj_ofuncs }, @@ -370,6 +505,23 @@ nouveau_device_sclass[] = { }; static int +nouveau_device_event_ctor(void *data, u32 size, struct nvkm_notify *notify) +{ + if (!WARN_ON(size != 0)) { + notify->size = 0; + notify->types = 1; + notify->index = 0; + return 0; + } + return -EINVAL; +} + +static const struct nvkm_event_func +nouveau_device_event_func = { + .ctor = nouveau_device_event_ctor, +}; + +static int nouveau_device_fini(struct nouveau_object *object, bool suspend) { struct nouveau_device *device = (void *)object; @@ -386,7 +538,7 @@ nouveau_device_fini(struct nouveau_object *object, bool suspend) } } - ret = 0; + ret = nvkm_acpi_fini(device, suspend); fail: for (; ret && i < NVDEV_SUBDEV_NR; i++) { if ((subdev = device->subdev[i])) { @@ -407,7 +559,11 @@ nouveau_device_init(struct nouveau_object *object) { struct nouveau_device *device = (void *)object; struct nouveau_object *subdev; - int ret, i; + int ret, i = 0; + + ret = nvkm_acpi_init(device); + if (ret) + goto fail; for (i = 0; i < NVDEV_SUBDEV_NR; i++) { if ((subdev = device->subdev[i])) { @@ -430,6 +586,8 @@ fail: } } + if (ret) + nvkm_acpi_fini(device, false); return ret; } @@ -438,6 +596,8 @@ nouveau_device_dtor(struct nouveau_object *object) { struct nouveau_device *device = (void *)object; + nvkm_event_fini(&device->event); + mutex_lock(&nv_devices_mutex); list_del(&device->head); mutex_unlock(&nv_devices_mutex); @@ -478,31 +638,6 @@ nv_device_resource_len(struct nouveau_device *device, unsigned int bar) } } -dma_addr_t -nv_device_map_page(struct nouveau_device *device, struct page *page) -{ - dma_addr_t ret; - - if (nv_device_is_pci(device)) { - ret = pci_map_page(device->pdev, page, 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(device->pdev, ret)) - ret = 0; - } else { - ret = page_to_phys(page); - } - - return ret; -} - -void -nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr) -{ - if (nv_device_is_pci(device)) - pci_unmap_page(device->pdev, addr, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); -} - int nv_device_get_irq(struct nouveau_device *device, bool stall) { @@ -560,6 +695,9 @@ nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name, nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE"); nv_engine(device)->sclass = nouveau_device_sclass; list_add(&device->head, &nv_devices); + + ret = nvkm_event_init(&nouveau_device_event_func, 1, 1, + &device->event); done: mutex_unlock(&nv_devices_mutex); return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c index 4b69bf56ed01..e34101a3490e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c @@ -22,55 +22,82 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ +#include <core/client.h> #include <core/object.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> +#include <nvif/ioctl.h> #include <subdev/clock.h> #include "priv.h" static int -nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nouveau_control_mthd_pstate_info(struct nouveau_object *object, + void *data, u32 size) { + union { + struct nvif_control_pstate_info_v0 v0; + } *args = data; struct nouveau_clock *clk = nouveau_clock(object); - struct nv_control_pstate_info *args = data; + int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(object, "control pstate info size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "control pstate info vers %d\n", + args->v0.version); + } else + return ret; if (clk) { - args->count = clk->state_nr; - args->ustate = clk->ustate; - args->pstate = clk->pstate; + args->v0.count = clk->state_nr; + args->v0.ustate_ac = clk->ustate_ac; + args->v0.ustate_dc = clk->ustate_dc; + args->v0.pwrsrc = clk->pwrsrc; + args->v0.pstate = clk->pstate; } else { - args->count = 0; - args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE; - args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN; + args->v0.count = 0; + args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; + args->v0.ustate_dc = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; + args->v0.pwrsrc = -ENOSYS; + args->v0.pstate = NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN; } return 0; } static int -nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nouveau_control_mthd_pstate_attr(struct nouveau_object *object, + void *data, u32 size) { + union { + struct nvif_control_pstate_attr_v0 v0; + } *args = data; struct nouveau_clock *clk = nouveau_clock(object); - struct nv_control_pstate_attr *args = data; struct nouveau_clocks *domain; struct nouveau_pstate *pstate; struct nouveau_cstate *cstate; int i = 0, j = -1; u32 lo, hi; - - if ((size < sizeof(*args)) || !clk || - (args->state >= 0 && args->state >= clk->state_nr)) - return -EINVAL; + int ret; + + nv_ioctl(object, "control pstate attr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "control pstate attr vers %d state %d " + "index %d\n", + args->v0.version, args->v0.state, args->v0.index); + if (!clk) + return -ENODEV; + if (args->v0.state < NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) + return -EINVAL; + if (args->v0.state >= clk->state_nr) + return -EINVAL; + } else + return ret; domain = clk->domains; while (domain->name != nv_clk_src_max) { - if (domain->mname && ++j == args->index) + if (domain->mname && ++j == args->v0.index) break; domain++; } @@ -78,9 +105,9 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, if (domain->name == nv_clk_src_max) return -EINVAL; - if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) { + if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) { list_for_each_entry(pstate, &clk->states, head) { - if (i++ == args->state) + if (i++ == args->v0.state) break; } @@ -91,21 +118,21 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, hi = max(hi, cstate->domain[domain->name]); } - args->state = pstate->pstate; + args->v0.state = pstate->pstate; } else { lo = max(clk->read(clk, domain->name), 0); hi = lo; } - snprintf(args->name, sizeof(args->name), "%s", domain->mname); - snprintf(args->unit, sizeof(args->unit), "MHz"); - args->min = lo / domain->mdiv; - args->max = hi / domain->mdiv; + snprintf(args->v0.name, sizeof(args->v0.name), "%s", domain->mname); + snprintf(args->v0.unit, sizeof(args->v0.unit), "MHz"); + args->v0.min = lo / domain->mdiv; + args->v0.max = hi / domain->mdiv; - args->index = 0; + args->v0.index = 0; while ((++domain)->name != nv_clk_src_max) { if (domain->mname) { - args->index = ++j; + args->v0.index = ++j; break; } } @@ -114,31 +141,65 @@ nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, } static int -nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nouveau_control_mthd_pstate_user(struct nouveau_object *object, + void *data, u32 size) { + union { + struct nvif_control_pstate_user_v0 v0; + } *args = data; struct nouveau_clock *clk = nouveau_clock(object); - struct nv_control_pstate_user *args = data; + int ret; + + nv_ioctl(object, "control pstate user size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "control pstate user vers %d ustate %d " + "pwrsrc %d\n", args->v0.version, + args->v0.ustate, args->v0.pwrsrc); + if (!clk) + return -ENODEV; + } else + return ret; + + if (args->v0.pwrsrc >= 0) { + ret |= nouveau_clock_ustate(clk, args->v0.ustate, args->v0.pwrsrc); + } else { + ret |= nouveau_clock_ustate(clk, args->v0.ustate, 0); + ret |= nouveau_clock_ustate(clk, args->v0.ustate, 1); + } - if (size < sizeof(*args) || !clk) - return -EINVAL; + return ret; +} - return nouveau_clock_ustate(clk, args->state); +static int +nouveau_control_mthd(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + switch (mthd) { + case NVIF_CONTROL_PSTATE_INFO: + return nouveau_control_mthd_pstate_info(object, data, size); + case NVIF_CONTROL_PSTATE_ATTR: + return nouveau_control_mthd_pstate_attr(object, data, size); + case NVIF_CONTROL_PSTATE_USER: + return nouveau_control_mthd_pstate_user(object, data, size); + default: + break; + } + return -EINVAL; } +static struct nouveau_ofuncs +nouveau_control_ofuncs = { + .ctor = _nouveau_object_ctor, + .dtor = nouveau_object_destroy, + .init = nouveau_object_init, + .fini = nouveau_object_fini, + .mthd = nouveau_control_mthd, +}; + struct nouveau_oclass nouveau_control_oclass[] = { - { .handle = NV_CONTROL_CLASS, - .ofuncs = &nouveau_object_ofuncs, - .omthds = (struct nouveau_omthds[]) { - { NV_CONTROL_PSTATE_INFO, - NV_CONTROL_PSTATE_INFO, nouveau_control_mthd_pstate_info }, - { NV_CONTROL_PSTATE_ATTR, - NV_CONTROL_PSTATE_ATTR, nouveau_control_mthd_pstate_attr }, - { NV_CONTROL_PSTATE_USER, - NV_CONTROL_PSTATE_USER, nouveau_control_mthd_pstate_user }, - {}, - }, + { .handle = NVIF_IOCTL_NEW_V0_CONTROL, + .ofuncs = &nouveau_control_ofuncs }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c index a520029e25d9..377ec0b8851e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c @@ -33,7 +33,7 @@ #include <subdev/mc.h> #include <subdev/timer.h> #include <subdev/fb.h> -#include <subdev/ltcg.h> +#include <subdev/ltc.h> #include <subdev/ibus.h> #include <subdev/instmem.h> #include <subdev/vm.h> @@ -68,20 +68,20 @@ gm100_identify(struct nouveau_device *device) #endif device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = gm107_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gm107_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; #if 0 - device->oclass[NVDEV_SUBDEV_PWR ] = &nv108_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; #endif - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = gm107_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c index 40b29d0214cb..573b55f5c2f9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c @@ -56,7 +56,7 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass; @@ -74,7 +74,7 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c index 5f7c25ff523d..183a85a6204e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c @@ -58,7 +58,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; @@ -75,7 +75,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; @@ -94,7 +94,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; @@ -113,7 +113,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; @@ -132,7 +132,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; @@ -151,7 +151,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; @@ -170,7 +170,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; @@ -189,7 +189,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c index 75fed11bba0a..aa564c68a920 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c @@ -59,7 +59,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv20_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass; @@ -78,7 +78,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass; @@ -97,7 +97,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass; @@ -116,7 +116,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c index 36919d7db7cc..11bd31da82ab 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c @@ -59,7 +59,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass; @@ -78,7 +78,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv35_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass; @@ -97,7 +97,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass; @@ -117,7 +117,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv36_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass; @@ -137,7 +137,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index 1130a62be2c7..e96c223cb797 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c @@ -65,7 +65,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -88,7 +88,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -111,7 +111,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -134,7 +134,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -157,7 +157,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -180,7 +180,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -203,7 +203,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -226,7 +226,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -249,7 +249,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -272,7 +272,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -295,7 +295,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -318,7 +318,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -341,7 +341,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -364,7 +364,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -387,7 +387,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; @@ -410,7 +410,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv04_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c index ef0b0bde1a91..932f84fae459 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c @@ -74,7 +74,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -99,7 +99,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -127,7 +127,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -155,7 +155,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -183,7 +183,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -211,7 +211,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -239,7 +239,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -267,7 +267,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -295,7 +295,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -323,7 +323,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -350,9 +350,9 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -380,9 +380,9 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -409,9 +409,9 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; @@ -438,9 +438,9 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nva3_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nv50_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 8d55ed633b19..b4a2917ce555 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c @@ -33,7 +33,7 @@ #include <subdev/mc.h> #include <subdev/timer.h> #include <subdev/fb.h> -#include <subdev/ltcg.h> +#include <subdev/ltc.h> #include <subdev/ibus.h> #include <subdev/instmem.h> #include <subdev/vm.h> @@ -70,14 +70,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc0_graph_oclass; @@ -102,14 +102,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; @@ -134,14 +134,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; @@ -165,14 +165,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; @@ -197,14 +197,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; @@ -229,14 +229,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc1_graph_oclass; @@ -260,14 +260,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvc0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvc0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc8_graph_oclass; @@ -292,14 +292,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvd9_graph_oclass; @@ -323,12 +323,12 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gf100_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvd7_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 2d1e97d4264f..54ec53bc6252 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -33,7 +33,7 @@ #include <subdev/mc.h> #include <subdev/timer.h> #include <subdev/fb.h> -#include <subdev/ltcg.h> +#include <subdev/ltc.h> #include <subdev/ibus.h> #include <subdev/instmem.h> #include <subdev/vm.h> @@ -70,14 +70,14 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = gk104_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; @@ -103,14 +103,14 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; @@ -136,14 +136,14 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = gk104_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; @@ -158,15 +158,16 @@ nve0_identify(struct nouveau_device *device) break; case 0xea: device->cname = "GK20A"; - device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &gk20a_clock_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; - device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_SUBDEV_BAR ] = &gk20a_bar_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass; @@ -186,14 +187,14 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass; @@ -219,17 +220,17 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nvd0_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; - device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass; + device->oclass[NVDEV_ENGINE_GR ] = gk110b_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; @@ -248,18 +249,18 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; - device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; - device->oclass[NVDEV_SUBDEV_PWR ] = &nv108_pwr_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass; device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; - device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/base.c b/drivers/gpu/drm/nouveau/core/engine/disp/base.c index 9c38c5e40500..22d55f6cde50 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/base.c @@ -22,23 +22,93 @@ * Authors: Ben Skeggs */ +#include <core/os.h> +#include <nvif/unpack.h> +#include <nvif/class.h> +#include <nvif/event.h> + #include "priv.h" #include "outp.h" #include "conn.h" +int +nouveau_disp_vblank_ctor(void *data, u32 size, struct nvkm_notify *notify) +{ + struct nouveau_disp *disp = + container_of(notify->event, typeof(*disp), vblank); + union { + struct nvif_notify_head_req_v0 v0; + } *req = data; + int ret; + + if (nvif_unpack(req->v0, 0, 0, false)) { + notify->size = sizeof(struct nvif_notify_head_rep_v0); + if (ret = -ENXIO, req->v0.head <= disp->vblank.index_nr) { + notify->types = 1; + notify->index = req->v0.head; + return 0; + } + } + + return ret; +} + +void +nouveau_disp_vblank(struct nouveau_disp *disp, int head) +{ + struct nvif_notify_head_rep_v0 rep = {}; + nvkm_event_send(&disp->vblank, 1, head, &rep, sizeof(rep)); +} + static int -nouveau_disp_hpd_check(struct nouveau_event *event, u32 types, int index) +nouveau_disp_hpd_ctor(void *data, u32 size, struct nvkm_notify *notify) { - struct nouveau_disp *disp = event->priv; + struct nouveau_disp *disp = + container_of(notify->event, typeof(*disp), hpd); + union { + struct nvif_notify_conn_req_v0 v0; + } *req = data; struct nvkm_output *outp; - list_for_each_entry(outp, &disp->outp, head) { - if (outp->conn->index == index) { - if (outp->conn->hpd.event) - return 0; - break; + int ret; + + if (nvif_unpack(req->v0, 0, 0, false)) { + notify->size = sizeof(struct nvif_notify_conn_rep_v0); + list_for_each_entry(outp, &disp->outp, head) { + if (ret = -ENXIO, outp->conn->index == req->v0.conn) { + if (ret = -ENODEV, outp->conn->hpd.event) { + notify->types = req->v0.mask; + notify->index = req->v0.conn; + ret = 0; + } + break; + } } } - return -ENOSYS; + + return ret; +} + +static const struct nvkm_event_func +nouveau_disp_hpd_func = { + .ctor = nouveau_disp_hpd_ctor +}; + +int +nouveau_disp_ntfy(struct nouveau_object *object, u32 type, + struct nvkm_event **event) +{ + struct nouveau_disp *disp = (void *)object->engine; + switch (type) { + case NV04_DISP_NTFY_VBLANK: + *event = &disp->vblank; + return 0; + case NV04_DISP_NTFY_CONN: + *event = &disp->hpd; + return 0; + default: + break; + } + return -EINVAL; } int @@ -97,7 +167,8 @@ _nouveau_disp_dtor(struct nouveau_object *object) struct nouveau_disp *disp = (void *)object; struct nvkm_output *outp, *outt; - nouveau_event_destroy(&disp->vblank); + nvkm_event_fini(&disp->vblank); + nvkm_event_fini(&disp->hpd); if (disp->outp.next) { list_for_each_entry_safe(outp, outt, &disp->outp, head) { @@ -157,14 +228,11 @@ nouveau_disp_create_(struct nouveau_object *parent, hpd = max(hpd, (u8)(dcbE.connector + 1)); } - ret = nouveau_event_create(3, hpd, &disp->hpd); + ret = nvkm_event_init(&nouveau_disp_hpd_func, 3, hpd, &disp->hpd); if (ret) return ret; - disp->hpd->priv = disp; - disp->hpd->check = nouveau_disp_hpd_check; - - ret = nouveau_event_create(1, heads, &disp->vblank); + ret = nvkm_event_init(impl->vblank, 1, heads, &disp->vblank); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/conn.c b/drivers/gpu/drm/nouveau/core/engine/disp/conn.c index 4ffbc70ecf5a..3d1070228977 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/conn.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/conn.c @@ -22,39 +22,41 @@ * Authors: Ben Skeggs */ +#include <core/os.h> +#include <nvif/event.h> + #include <subdev/gpio.h> #include "conn.h" #include "outp.h" -static void -nvkm_connector_hpd_work(struct work_struct *w) +static int +nvkm_connector_hpd(struct nvkm_notify *notify) { - struct nvkm_connector *conn = container_of(w, typeof(*conn), hpd.work); + struct nvkm_connector *conn = container_of(notify, typeof(*conn), hpd); struct nouveau_disp *disp = nouveau_disp(conn); struct nouveau_gpio *gpio = nouveau_gpio(conn); - u32 send = NVKM_HPD_UNPLUG; - if (gpio->get(gpio, 0, DCB_GPIO_UNUSED, conn->hpd.event->index)) - send = NVKM_HPD_PLUG; - nouveau_event_trigger(disp->hpd, send, conn->index); - nouveau_event_get(conn->hpd.event); -} + const struct nvkm_gpio_ntfy_rep *line = notify->data; + struct nvif_notify_conn_rep_v0 rep; + int index = conn->index; -static int -nvkm_connector_hpd(void *data, u32 type, int index) -{ - struct nvkm_connector *conn = data; - DBG("HPD: %d\n", type); - schedule_work(&conn->hpd.work); - return NVKM_EVENT_DROP; + DBG("HPD: %d\n", line->mask); + + if (!gpio->get(gpio, 0, DCB_GPIO_UNUSED, conn->hpd.index)) + rep.mask = NVIF_NOTIFY_CONN_V0_UNPLUG; + else + rep.mask = NVIF_NOTIFY_CONN_V0_PLUG; + rep.version = 0; + + nvkm_event_send(&disp->hpd, rep.mask, index, &rep, sizeof(rep)); + return NVKM_NOTIFY_KEEP; } int _nvkm_connector_fini(struct nouveau_object *object, bool suspend) { struct nvkm_connector *conn = (void *)object; - if (conn->hpd.event) - nouveau_event_put(conn->hpd.event); + nvkm_notify_put(&conn->hpd); return nouveau_object_fini(&conn->base, suspend); } @@ -63,10 +65,8 @@ _nvkm_connector_init(struct nouveau_object *object) { struct nvkm_connector *conn = (void *)object; int ret = nouveau_object_init(&conn->base); - if (ret == 0) { - if (conn->hpd.event) - nouveau_event_get(conn->hpd.event); - } + if (ret == 0) + nvkm_notify_get(&conn->hpd); return ret; } @@ -74,7 +74,7 @@ void _nvkm_connector_dtor(struct nouveau_object *object) { struct nvkm_connector *conn = (void *)object; - nouveau_event_ref(NULL, &conn->hpd.event); + nvkm_notify_fini(&conn->hpd); nouveau_object_destroy(&conn->base); } @@ -116,19 +116,24 @@ nvkm_connector_create_(struct nouveau_object *parent, if ((info->hpd = ffs(info->hpd))) { if (--info->hpd >= ARRAY_SIZE(hpd)) { ERR("hpd %02x unknown\n", info->hpd); - goto done; + return 0; } info->hpd = hpd[info->hpd]; ret = gpio->find(gpio, 0, info->hpd, DCB_GPIO_UNUSED, &func); if (ret) { ERR("func %02x lookup failed, %d\n", info->hpd, ret); - goto done; + return 0; } - ret = nouveau_event_new(gpio->events, NVKM_GPIO_TOGGLED, - func.line, nvkm_connector_hpd, - conn, &conn->hpd.event); + ret = nvkm_notify_init(&gpio->event, nvkm_connector_hpd, true, + &(struct nvkm_gpio_ntfy_req) { + .mask = NVKM_GPIO_TOGGLED, + .line = func.line, + }, + sizeof(struct nvkm_gpio_ntfy_req), + sizeof(struct nvkm_gpio_ntfy_rep), + &conn->hpd); if (ret) { ERR("func %02x failed, %d\n", info->hpd, ret); } else { @@ -136,8 +141,6 @@ nvkm_connector_create_(struct nouveau_object *parent, } } -done: - INIT_WORK(&conn->hpd.work, nvkm_connector_hpd_work); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/conn.h b/drivers/gpu/drm/nouveau/core/engine/disp/conn.h index 035ebeacbb1c..55e5f5c82c14 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/conn.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/conn.h @@ -10,10 +10,7 @@ struct nvkm_connector { struct nvbios_connE info; int index; - struct { - struct nouveau_eventh *event; - struct work_struct work; - } hpd; + struct nvkm_notify hpd; }; #define nvkm_connector_create(p,e,c,b,i,d) \ diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c index a66b27c0fcab..b36addff06a9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> @@ -32,13 +33,28 @@ #include "nv50.h" int -nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data) +nv50_dac_power(NV50_DISP_MTHD_V1) { - const u32 stat = (data & NV50_DISP_DAC_PWR_HSYNC) | - (data & NV50_DISP_DAC_PWR_VSYNC) | - (data & NV50_DISP_DAC_PWR_DATA) | - (data & NV50_DISP_DAC_PWR_STATE); - const u32 doff = (or * 0x800); + const u32 doff = outp->or * 0x800; + union { + struct nv50_disp_dac_pwr_v0 v0; + } *args = data; + u32 stat; + int ret; + + nv_ioctl(object, "disp dac pwr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp dac pwr vers %d state %d data %d " + "vsync %d hsync %d\n", + args->v0.version, args->v0.state, args->v0.data, + args->v0.vsync, args->v0.hsync); + stat = 0x00000040 * !args->v0.state; + stat |= 0x00000010 * !args->v0.data; + stat |= 0x00000004 * !args->v0.vsync; + stat |= 0x00000001 * !args->v0.hsync; + } else + return ret; + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_mask(priv, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); @@ -46,9 +62,24 @@ nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data) } int -nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) +nv50_dac_sense(NV50_DISP_MTHD_V1) { - const u32 doff = (or * 0x800); + union { + struct nv50_disp_dac_load_v0 v0; + } *args = data; + const u32 doff = outp->or * 0x800; + u32 loadval; + int ret; + + nv_ioctl(object, "disp dac load size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp dac load vers %d data %08x\n", + args->v0.version, args->v0.data); + if (args->v0.data & 0xfff00000) + return -EINVAL; + loadval = args->v0.data; + } else + return ret; nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); @@ -61,38 +92,10 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); - nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval); + nv_debug(priv, "DAC%d sense: 0x%08x\n", outp->or, loadval); if (!(loadval & 0x80000000)) return -ETIMEDOUT; - return (loadval & 0x38000000) >> 27; -} - -int -nv50_dac_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - const u8 or = (mthd & NV50_DISP_DAC_MTHD_OR); - u32 *data = args; - int ret; - - if (size < sizeof(u32)) - return -EINVAL; - - switch (mthd & ~0x3f) { - case NV50_DISP_DAC_PWR: - ret = priv->dac.power(priv, or, data[0]); - break; - case NV50_DISP_DAC_LOAD: - ret = priv->dac.sense(priv, or, data[0]); - if (ret >= 0) { - data[0] = ret; - ret = 0; - } - break; - default: - BUG_ON(1); - } - - return ret; + args->v0.load = (loadval & 0x38000000) >> 27; + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c index 5a5b59b21130..39890221b91c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c @@ -30,7 +30,7 @@ #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "dport.h" #include "outpdp.h" @@ -335,7 +335,7 @@ nouveau_dp_train(struct work_struct *w) int ret; /* bring capabilities within encoder limits */ - if (nv_mclass(disp) < NVD0_DISP_CLASS) + if (nv_mclass(disp) < GF110_DISP) outp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED; if ((outp->dpcd[2] & 0x1f) > outp->base.info.dpconf.link_nr) { outp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT; @@ -354,7 +354,7 @@ nouveau_dp_train(struct work_struct *w) cfg--; /* disable link interrupt handling during link training */ - nouveau_event_put(outp->irq); + nvkm_notify_put(&outp->irq); /* enable down-spreading and execute pre-train script from vbios */ dp_link_train_init(dp, outp->dpcd[3] & 0x01); @@ -395,5 +395,5 @@ nouveau_dp_train(struct work_struct *w) DBG("training complete\n"); atomic_set(&outp->lt.done, 1); wake_up(&outp->lt.wait); - nouveau_event_get(outp->irq); + nvkm_notify_get(&outp->irq); } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c index 9fc7447fec90..d54da8b5f87e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -35,17 +35,17 @@ static struct nouveau_oclass gm107_disp_sclass[] = { - { GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs }, - { GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs }, - { GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs }, - { GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs }, - { GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs }, + { GM107_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, + { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, + { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, + { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, + { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, {} }; static struct nouveau_oclass gm107_disp_base_oclass[] = { - { GM107_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds }, + { GM107_DISP, &nvd0_disp_base_ofuncs }, {} }; @@ -93,9 +93,11 @@ gm107_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nvd0_disp_vblank_func, .base.outp = nvd0_disp_outp_sclass, .mthd.core = &nve0_disp_mast_mthd_chan, .mthd.base = &nvd0_disp_sync_mthd_chan, .mthd.ovly = &nve0_disp_ovly_mthd_chan, .mthd.prev = -0x020000, + .head.scanoutpos = nvd0_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c index a19e7d79b847..8b4e06abe533 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanva3.c @@ -22,25 +22,37 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include "nv50.h" int -nva3_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) +nva3_hda_eld(NV50_DISP_MTHD_V1) { - const u32 soff = (or * 0x800); - int i; + union { + struct nv50_disp_sor_hda_eld_v0 v0; + } *args = data; + const u32 soff = outp->or * 0x800; + int ret, i; - if (data && data[0]) { + nv_ioctl(object, "disp sor hda eld size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, true)) { + nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version); + if (size > 0x60) + return -E2BIG; + } else + return ret; + + if (size && args->v0.data[0]) { for (i = 0; i < size; i++) - nv_wr32(priv, 0x61c440 + soff, (i << 8) | data[i]); + nv_wr32(priv, 0x61c440 + soff, (i << 8) | args->v0.data[0]); for (; i < 0x60; i++) nv_wr32(priv, 0x61c440 + soff, (i << 8)); nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000003); } else - if (data) { + if (size) { nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000001); } else { nv_mask(priv, 0x61c448 + soff, 0x80000003, 0x80000000); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c index 717639386ced..baf558fc12fb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdanvd0.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> @@ -33,19 +34,30 @@ #include "nv50.h" int -nvd0_hda_eld(struct nv50_disp_priv *priv, int or, u8 *data, u32 size) +nvd0_hda_eld(NV50_DISP_MTHD_V1) { - const u32 soff = (or * 0x030); - int i; + union { + struct nv50_disp_sor_hda_eld_v0 v0; + } *args = data; + const u32 soff = outp->or * 0x030; + int ret, i; - if (data && data[0]) { + nv_ioctl(object, "disp sor hda eld size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, true)) { + nv_ioctl(object, "disp sor hda eld vers %d\n", args->v0.version); + if (size > 0x60) + return -E2BIG; + } else + return ret; + + if (size && args->v0.data[0]) { for (i = 0; i < size; i++) - nv_wr32(priv, 0x10ec00 + soff, (i << 8) | data[i]); + nv_wr32(priv, 0x10ec00 + soff, (i << 8) | args->v0.data[i]); for (; i < 0x60; i++) nv_wr32(priv, 0x10ec00 + soff, (i << 8)); nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000003); } else - if (data) { + if (size) { nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000001); } else { nv_mask(priv, 0x10ec10 + soff, 0x80000003, 0x80000000); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c index 7fdade6e604d..fa276dede9cd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminv84.c @@ -22,17 +22,38 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include "nv50.h" int -nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) +nv84_hdmi_ctrl(NV50_DISP_MTHD_V1) { const u32 hoff = (head * 0x800); + union { + struct nv50_disp_sor_hdmi_pwr_v0 v0; + } *args = data; + u32 ctrl; + int ret; - if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { + nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d " + "max_ac_packet %d rekey %d\n", + args->v0.version, args->v0.state, + args->v0.max_ac_packet, args->v0.rekey); + if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) + return -EINVAL; + ctrl = 0x40000000 * !!args->v0.state; + ctrl |= args->v0.max_ac_packet << 16; + ctrl |= args->v0.rekey; + ctrl |= 0x1f000000; /* ??? */ + } else + return ret; + + if (!(ctrl & 0x40000000)) { nv_mask(priv, 0x6165a4 + hoff, 0x40000000, 0x00000000); nv_mask(priv, 0x616520 + hoff, 0x00000001, 0x00000000); nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000000); @@ -65,6 +86,6 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ /* HDMI_CTRL */ - nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, data | 0x1f000000 /* ??? */); + nv_mask(priv, 0x6165a4 + hoff, 0x5f1f007f, ctrl); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c index db8c6fd46278..57eeed1d1942 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminva3.c @@ -22,17 +22,38 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include "nv50.h" int -nva3_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) +nva3_hdmi_ctrl(NV50_DISP_MTHD_V1) { - const u32 soff = (or * 0x800); + const u32 soff = outp->or * 0x800; + union { + struct nv50_disp_sor_hdmi_pwr_v0 v0; + } *args = data; + u32 ctrl; + int ret; - if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { + nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d " + "max_ac_packet %d rekey %d\n", + args->v0.version, args->v0.state, + args->v0.max_ac_packet, args->v0.rekey); + if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) + return -EINVAL; + ctrl = 0x40000000 * !!args->v0.state; + ctrl |= args->v0.max_ac_packet << 16; + ctrl |= args->v0.rekey; + ctrl |= 0x1f000000; /* ??? */ + } else + return ret; + + if (!(ctrl & 0x40000000)) { nv_mask(priv, 0x61c5a4 + soff, 0x40000000, 0x00000000); nv_mask(priv, 0x61c520 + soff, 0x00000001, 0x00000000); nv_mask(priv, 0x61c500 + soff, 0x00000001, 0x00000000); @@ -65,6 +86,6 @@ nva3_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) nv_mask(priv, 0x61733c, 0x00100000, 0x00000000); /* !RESETF */ /* HDMI_CTRL */ - nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, data | 0x1f000000 /* ??? */); + nv_mask(priv, 0x61c5a4 + soff, 0x5f1f007f, ctrl); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c index 5151bb261832..3106d295b48d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c @@ -22,17 +22,37 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include "nv50.h" int -nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) +nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1) { const u32 hoff = (head * 0x800); + union { + struct nv50_disp_sor_hdmi_pwr_v0 v0; + } *args = data; + u32 ctrl; + int ret; - if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { + nv_ioctl(object, "disp sor hdmi ctrl size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor hdmi ctrl vers %d state %d " + "max_ac_packet %d rekey %d\n", + args->v0.version, args->v0.state, + args->v0.max_ac_packet, args->v0.rekey); + if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) + return -EINVAL; + ctrl = 0x40000000 * !!args->v0.state; + ctrl |= args->v0.max_ac_packet << 16; + ctrl |= args->v0.rekey; + } else + return ret; + + if (!(ctrl & 0x40000000)) { nv_mask(priv, 0x616798 + hoff, 0x40000000, 0x00000000); nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000); nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000); @@ -54,7 +74,7 @@ nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000001); /* HDMI_CTRL */ - nv_mask(priv, 0x616798 + hoff, 0x401f007f, data); + nv_mask(priv, 0x616798 + hoff, 0x401f007f, ctrl); /* NFI, audio doesn't work without it though.. */ nv_mask(priv, 0x616548 + hoff, 0x00000070, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c index a32666ed0c47..366f315fc9a5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c @@ -24,60 +24,100 @@ #include "priv.h" +#include <core/client.h> #include <core/event.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> struct nv04_disp_priv { struct nouveau_disp base; }; static int -nv04_disp_scanoutpos(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nv04_disp_scanoutpos(struct nouveau_object *object, struct nv04_disp_priv *priv, + void *data, u32 size, int head) { - struct nv04_disp_priv *priv = (void *)object->engine; - struct nv04_display_scanoutpos *args = data; - const int head = (mthd & NV04_DISP_MTHD_HEAD); + const u32 hoff = head * 0x2000; + union { + struct nv04_disp_scanoutpos_v0 v0; + } *args = data; u32 line; + int ret; + + nv_ioctl(object, "disp scanoutpos size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version); + args->v0.vblanks = nv_rd32(priv, 0x680800 + hoff) & 0xffff; + args->v0.vtotal = nv_rd32(priv, 0x680804 + hoff) & 0xffff; + args->v0.vblanke = args->v0.vtotal - 1; + + args->v0.hblanks = nv_rd32(priv, 0x680820 + hoff) & 0xffff; + args->v0.htotal = nv_rd32(priv, 0x680824 + hoff) & 0xffff; + args->v0.hblanke = args->v0.htotal - 1; + + /* + * If output is vga instead of digital then vtotal/htotal is + * invalid so we have to give up and trigger the timestamping + * fallback in the drm core. + */ + if (!args->v0.vtotal || !args->v0.htotal) + return -ENOTSUPP; + + args->v0.time[0] = ktime_to_ns(ktime_get()); + line = nv_rd32(priv, 0x600868 + hoff); + args->v0.time[1] = ktime_to_ns(ktime_get()); + args->v0.hline = (line & 0xffff0000) >> 16; + args->v0.vline = (line & 0x0000ffff); + } else + return ret; - if (size < sizeof(*args)) - return -EINVAL; - - args->vblanks = nv_rd32(priv, 0x680800 + (head * 0x2000)) & 0xffff; - args->vtotal = nv_rd32(priv, 0x680804 + (head * 0x2000)) & 0xffff; - args->vblanke = args->vtotal - 1; - - args->hblanks = nv_rd32(priv, 0x680820 + (head * 0x2000)) & 0xffff; - args->htotal = nv_rd32(priv, 0x680824 + (head * 0x2000)) & 0xffff; - args->hblanke = args->htotal - 1; - - /* - * If output is vga instead of digital then vtotal/htotal is invalid - * so we have to give up and trigger the timestamping fallback in the - * drm core. - */ - if (!args->vtotal || !args->htotal) - return -ENOTSUPP; - - args->time[0] = ktime_to_ns(ktime_get()); - line = nv_rd32(priv, 0x600868 + (head * 0x2000)); - args->time[1] = ktime_to_ns(ktime_get()); - args->hline = (line & 0xffff0000) >> 16; - args->vline = (line & 0x0000ffff); return 0; } -#define HEAD_MTHD(n) (n), (n) + 0x01 +static int +nv04_disp_mthd(struct nouveau_object *object, u32 mthd, void *data, u32 size) +{ + union { + struct nv04_disp_mthd_v0 v0; + } *args = data; + struct nv04_disp_priv *priv = (void *)object->engine; + int head, ret; + + nv_ioctl(object, "disp mthd size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, true)) { + nv_ioctl(object, "disp mthd vers %d mthd %02x head %d\n", + args->v0.version, args->v0.method, args->v0.head); + mthd = args->v0.method; + head = args->v0.head; + } else + return ret; -static struct nouveau_omthds -nv04_disp_omthds[] = { - { HEAD_MTHD(NV04_DISP_SCANOUTPOS), nv04_disp_scanoutpos }, - {} + if (head < 0 || head >= 2) + return -ENXIO; + + switch (mthd) { + case NV04_DISP_SCANOUTPOS: + return nv04_disp_scanoutpos(object, priv, data, size, head); + default: + break; + } + + return -EINVAL; +} + +static struct nouveau_ofuncs +nv04_disp_ofuncs = { + .ctor = _nouveau_object_ctor, + .dtor = nouveau_object_destroy, + .init = nouveau_object_init, + .fini = nouveau_object_fini, + .mthd = nv04_disp_mthd, + .ntfy = nouveau_disp_ntfy, }; static struct nouveau_oclass nv04_disp_sclass[] = { - { NV04_DISP_CLASS, &nouveau_object_ofuncs, nv04_disp_omthds }, + { NV04_DISP, &nv04_disp_ofuncs }, {}, }; @@ -86,17 +126,26 @@ nv04_disp_sclass[] = { ******************************************************************************/ static void -nv04_disp_vblank_enable(struct nouveau_event *event, int type, int head) +nv04_disp_vblank_init(struct nvkm_event *event, int type, int head) { - nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001); + struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank); + nv_wr32(disp, 0x600140 + (head * 0x2000) , 0x00000001); } static void -nv04_disp_vblank_disable(struct nouveau_event *event, int type, int head) +nv04_disp_vblank_fini(struct nvkm_event *event, int type, int head) { - nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000); + struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank); + nv_wr32(disp, 0x600140 + (head * 0x2000) , 0x00000000); } +static const struct nvkm_event_func +nv04_disp_vblank_func = { + .ctor = nouveau_disp_vblank_ctor, + .init = nv04_disp_vblank_init, + .fini = nv04_disp_vblank_fini, +}; + static void nv04_disp_intr(struct nouveau_subdev *subdev) { @@ -106,12 +155,12 @@ nv04_disp_intr(struct nouveau_subdev *subdev) u32 pvideo; if (crtc0 & 0x00000001) { - nouveau_event_trigger(priv->base.vblank, 1, 0); + nouveau_disp_vblank(&priv->base, 0); nv_wr32(priv, 0x600100, 0x00000001); } if (crtc1 & 0x00000001) { - nouveau_event_trigger(priv->base.vblank, 1, 1); + nouveau_disp_vblank(&priv->base, 1); nv_wr32(priv, 0x602100, 0x00000001); } @@ -140,9 +189,6 @@ nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nv04_disp_sclass; nv_subdev(priv)->intr = nv04_disp_intr; - priv->base.vblank->priv = priv; - priv->base.vblank->enable = nv04_disp_vblank_enable; - priv->base.vblank->disable = nv04_disp_vblank_disable; return 0; } @@ -155,4 +201,5 @@ nv04_disp_oclass = &(struct nouveau_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .vblank = &nv04_disp_vblank_func, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 2283c442a10d..4b5bb5d58a54 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -23,10 +23,12 @@ */ #include <core/object.h> +#include <core/client.h> #include <core/parent.h> #include <core/handle.h> -#include <core/class.h> #include <core/enum.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> @@ -43,14 +45,16 @@ * EVO channel base class ******************************************************************************/ -int +static int nv50_disp_chan_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int chid, + struct nouveau_oclass *oclass, int head, int length, void **pobject) { + const struct nv50_disp_chan_impl *impl = (void *)oclass->ofuncs; struct nv50_disp_base *base = (void *)parent; struct nv50_disp_chan *chan; + int chid = impl->chid + head; int ret; if (base->chan & (1 << chid)) @@ -63,12 +67,14 @@ nv50_disp_chan_create_(struct nouveau_object *parent, chan = *pobject; if (ret) return ret; - chan->chid = chid; + + nv_parent(chan)->object_attach = impl->attach; + nv_parent(chan)->object_detach = impl->detach; return 0; } -void +static void nv50_disp_chan_destroy(struct nv50_disp_chan *chan) { struct nv50_disp_base *base = (void *)nv_object(chan)->parent; @@ -76,6 +82,16 @@ nv50_disp_chan_destroy(struct nv50_disp_chan *chan) nouveau_namedb_destroy(&chan->base); } +int +nv50_disp_chan_map(struct nouveau_object *object, u64 *addr, u32 *size) +{ + struct nv50_disp_chan *chan = (void *)object; + *addr = nv_device_resource_start(nv_device(object), 0) + + 0x640000 + (chan->chid * 0x1000); + *size = 0x001000; + return 0; +} + u32 nv50_disp_chan_rd32(struct nouveau_object *object, u64 addr) { @@ -115,16 +131,16 @@ nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie) nouveau_ramht_remove(base->ramht, cookie); } -int +static int nv50_disp_dmac_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, u32 pushbuf, int chid, + struct nouveau_oclass *oclass, u32 pushbuf, int head, int length, void **pobject) { struct nv50_disp_dmac *dmac; int ret; - ret = nv50_disp_chan_create_(parent, engine, oclass, chid, + ret = nv50_disp_chan_create_(parent, engine, oclass, head, length, pobject); dmac = *pobject; if (ret) @@ -397,27 +413,32 @@ nv50_disp_mast_mthd_chan = { } }; -static int +int nv50_disp_mast_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_display_mast_class *args = data; + union { + struct nv50_disp_core_channel_dma_v0 v0; + } *args = data; struct nv50_disp_dmac *mast; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create disp core channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create disp core channel dma vers %d " + "pushbuf %08x\n", + args->v0.version, args->v0.pushbuf); + } else + return ret; - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, + ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, 0, sizeof(*mast), (void **)&mast); *pobject = nv_object(mast); if (ret) return ret; - nv_parent(mast)->object_attach = nv50_disp_dmac_object_attach; - nv_parent(mast)->object_detach = nv50_disp_dmac_object_detach; return 0; } @@ -479,14 +500,18 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend) return nv50_disp_chan_fini(&mast->base, suspend); } -struct nouveau_ofuncs +struct nv50_disp_chan_impl nv50_disp_mast_ofuncs = { - .ctor = nv50_disp_mast_ctor, - .dtor = nv50_disp_dmac_dtor, - .init = nv50_disp_mast_init, - .fini = nv50_disp_mast_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_mast_ctor, + .base.dtor = nv50_disp_dmac_dtor, + .base.init = nv50_disp_mast_init, + .base.fini = nv50_disp_mast_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 0, + .attach = nv50_disp_dmac_object_attach, + .detach = nv50_disp_dmac_object_detach, }; /******************************************************************************* @@ -543,39 +568,51 @@ nv50_disp_sync_mthd_chan = { } }; -static int +int nv50_disp_sync_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_display_sync_class *args = data; + union { + struct nv50_disp_base_channel_dma_v0 v0; + } *args = data; + struct nv50_disp_priv *priv = (void *)engine; struct nv50_disp_dmac *dmac; int ret; - if (size < sizeof(*args) || args->head > 1) - return -EINVAL; + nv_ioctl(parent, "create disp base channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create disp base channel dma vers %d " + "pushbuf %08x head %d\n", + args->v0.version, args->v0.pushbuf, args->v0.head); + if (args->v0.head > priv->head.nr) + return -EINVAL; + } else + return ret; - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, - 1 + args->head, sizeof(*dmac), + ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, + args->v0.head, sizeof(*dmac), (void **)&dmac); *pobject = nv_object(dmac); if (ret) return ret; - nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach; - nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach; return 0; } -struct nouveau_ofuncs +struct nv50_disp_chan_impl nv50_disp_sync_ofuncs = { - .ctor = nv50_disp_sync_ctor, - .dtor = nv50_disp_dmac_dtor, - .init = nv50_disp_dmac_init, - .fini = nv50_disp_dmac_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_sync_ctor, + .base.dtor = nv50_disp_dmac_dtor, + .base.init = nv50_disp_dmac_init, + .base.fini = nv50_disp_dmac_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 1, + .attach = nv50_disp_dmac_object_attach, + .detach = nv50_disp_dmac_object_detach, }; /******************************************************************************* @@ -620,39 +657,51 @@ nv50_disp_ovly_mthd_chan = { } }; -static int +int nv50_disp_ovly_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_display_ovly_class *args = data; + union { + struct nv50_disp_overlay_channel_dma_v0 v0; + } *args = data; + struct nv50_disp_priv *priv = (void *)engine; struct nv50_disp_dmac *dmac; int ret; - if (size < sizeof(*args) || args->head > 1) - return -EINVAL; + nv_ioctl(parent, "create disp overlay channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create disp overlay channel dma vers %d " + "pushbuf %08x head %d\n", + args->v0.version, args->v0.pushbuf, args->v0.head); + if (args->v0.head > priv->head.nr) + return -EINVAL; + } else + return ret; - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, - 3 + args->head, sizeof(*dmac), + ret = nv50_disp_dmac_create_(parent, engine, oclass, args->v0.pushbuf, + args->v0.head, sizeof(*dmac), (void **)&dmac); *pobject = nv_object(dmac); if (ret) return ret; - nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach; - nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach; return 0; } -struct nouveau_ofuncs +struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs = { - .ctor = nv50_disp_ovly_ctor, - .dtor = nv50_disp_dmac_dtor, - .init = nv50_disp_dmac_init, - .fini = nv50_disp_dmac_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_ovly_ctor, + .base.dtor = nv50_disp_dmac_dtor, + .base.init = nv50_disp_dmac_init, + .base.fini = nv50_disp_dmac_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 3, + .attach = nv50_disp_dmac_object_attach, + .detach = nv50_disp_dmac_object_detach, }; /******************************************************************************* @@ -662,14 +711,14 @@ nv50_disp_ovly_ofuncs = { static int nv50_disp_pioc_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int chid, + struct nouveau_oclass *oclass, int head, int length, void **pobject) { - return nv50_disp_chan_create_(parent, engine, oclass, chid, + return nv50_disp_chan_create_(parent, engine, oclass, head, length, pobject); } -static void +void nv50_disp_pioc_dtor(struct nouveau_object *object) { struct nv50_disp_pioc *pioc = (void *)object; @@ -727,20 +776,29 @@ nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend) * EVO immediate overlay channel objects ******************************************************************************/ -static int +int nv50_disp_oimm_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_display_oimm_class *args = data; + union { + struct nv50_disp_overlay_v0 v0; + } *args = data; + struct nv50_disp_priv *priv = (void *)engine; struct nv50_disp_pioc *pioc; int ret; - if (size < sizeof(*args) || args->head > 1) - return -EINVAL; + nv_ioctl(parent, "create disp overlay size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create disp overlay vers %d head %d\n", + args->v0.version, args->v0.head); + if (args->v0.head > priv->head.nr) + return -EINVAL; + } else + return ret; - ret = nv50_disp_pioc_create_(parent, engine, oclass, 5 + args->head, + ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head, sizeof(*pioc), (void **)&pioc); *pobject = nv_object(pioc); if (ret) @@ -749,34 +807,45 @@ nv50_disp_oimm_ctor(struct nouveau_object *parent, return 0; } -struct nouveau_ofuncs +struct nv50_disp_chan_impl nv50_disp_oimm_ofuncs = { - .ctor = nv50_disp_oimm_ctor, - .dtor = nv50_disp_pioc_dtor, - .init = nv50_disp_pioc_init, - .fini = nv50_disp_pioc_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_oimm_ctor, + .base.dtor = nv50_disp_pioc_dtor, + .base.init = nv50_disp_pioc_init, + .base.fini = nv50_disp_pioc_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 5, }; /******************************************************************************* * EVO cursor channel objects ******************************************************************************/ -static int +int nv50_disp_curs_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_display_curs_class *args = data; + union { + struct nv50_disp_cursor_v0 v0; + } *args = data; + struct nv50_disp_priv *priv = (void *)engine; struct nv50_disp_pioc *pioc; int ret; - if (size < sizeof(*args) || args->head > 1) - return -EINVAL; + nv_ioctl(parent, "create disp cursor size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create disp cursor vers %d head %d\n", + args->v0.version, args->v0.head); + if (args->v0.head > priv->head.nr) + return -EINVAL; + } else + return ret; - ret = nv50_disp_pioc_create_(parent, engine, oclass, 7 + args->head, + ret = nv50_disp_pioc_create_(parent, engine, oclass, args->v0.head, sizeof(*pioc), (void **)&pioc); *pobject = nv_object(pioc); if (ret) @@ -785,14 +854,16 @@ nv50_disp_curs_ctor(struct nouveau_object *parent, return 0; } -struct nouveau_ofuncs +struct nv50_disp_chan_impl nv50_disp_curs_ofuncs = { - .ctor = nv50_disp_curs_ctor, - .dtor = nv50_disp_pioc_dtor, - .init = nv50_disp_pioc_init, - .fini = nv50_disp_pioc_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_curs_ctor, + .base.dtor = nv50_disp_pioc_dtor, + .base.init = nv50_disp_pioc_init, + .base.fini = nv50_disp_pioc_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 7, }; /******************************************************************************* @@ -800,47 +871,162 @@ nv50_disp_curs_ofuncs = { ******************************************************************************/ int -nv50_disp_base_scanoutpos(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0) { - struct nv50_disp_priv *priv = (void *)object->engine; - struct nv04_display_scanoutpos *args = data; - const int head = (mthd & NV50_DISP_MTHD_HEAD); - u32 blanke, blanks, total; + const u32 blanke = nv_rd32(priv, 0x610aec + (head * 0x540)); + const u32 blanks = nv_rd32(priv, 0x610af4 + (head * 0x540)); + const u32 total = nv_rd32(priv, 0x610afc + (head * 0x540)); + union { + struct nv04_disp_scanoutpos_v0 v0; + } *args = data; + int ret; + + nv_ioctl(object, "disp scanoutpos size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version); + args->v0.vblanke = (blanke & 0xffff0000) >> 16; + args->v0.hblanke = (blanke & 0x0000ffff); + args->v0.vblanks = (blanks & 0xffff0000) >> 16; + args->v0.hblanks = (blanks & 0x0000ffff); + args->v0.vtotal = ( total & 0xffff0000) >> 16; + args->v0.htotal = ( total & 0x0000ffff); + args->v0.time[0] = ktime_to_ns(ktime_get()); + args->v0.vline = /* vline read locks hline */ + nv_rd32(priv, 0x616340 + (head * 0x800)) & 0xffff; + args->v0.time[1] = ktime_to_ns(ktime_get()); + args->v0.hline = + nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff; + } else + return ret; - if (size < sizeof(*args) || head >= priv->head.nr) - return -EINVAL; - blanke = nv_rd32(priv, 0x610aec + (head * 0x540)); - blanks = nv_rd32(priv, 0x610af4 + (head * 0x540)); - total = nv_rd32(priv, 0x610afc + (head * 0x540)); - - args->vblanke = (blanke & 0xffff0000) >> 16; - args->hblanke = (blanke & 0x0000ffff); - args->vblanks = (blanks & 0xffff0000) >> 16; - args->hblanks = (blanks & 0x0000ffff); - args->vtotal = ( total & 0xffff0000) >> 16; - args->htotal = ( total & 0x0000ffff); - - args->time[0] = ktime_to_ns(ktime_get()); - args->vline = nv_rd32(priv, 0x616340 + (head * 0x800)) & 0xffff; - args->time[1] = ktime_to_ns(ktime_get()); /* vline read locks hline */ - args->hline = nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff; return 0; } -static void -nv50_disp_base_vblank_enable(struct nouveau_event *event, int type, int head) +int +nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, + void *data, u32 size) { - nv_mask(event->priv, 0x61002c, (4 << head), (4 << head)); -} + const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine); + union { + struct nv50_disp_mthd_v0 v0; + struct nv50_disp_mthd_v1 v1; + } *args = data; + struct nv50_disp_priv *priv = (void *)object->engine; + struct nvkm_output *outp = NULL; + struct nvkm_output *temp; + u16 type, mask = 0; + int head, ret; -static void -nv50_disp_base_vblank_disable(struct nouveau_event *event, int type, int head) -{ - nv_mask(event->priv, 0x61002c, (4 << head), 0); + if (mthd != NV50_DISP_MTHD) + return -EINVAL; + + nv_ioctl(object, "disp mthd size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, true)) { + nv_ioctl(object, "disp mthd vers %d mthd %02x head %d\n", + args->v0.version, args->v0.method, args->v0.head); + mthd = args->v0.method; + head = args->v0.head; + } else + if (nvif_unpack(args->v1, 1, 1, true)) { + nv_ioctl(object, "disp mthd vers %d mthd %02x " + "type %04x mask %04x\n", + args->v1.version, args->v1.method, + args->v1.hasht, args->v1.hashm); + mthd = args->v1.method; + type = args->v1.hasht; + mask = args->v1.hashm; + head = ffs((mask >> 8) & 0x0f) - 1; + } else + return ret; + + if (head < 0 || head >= priv->head.nr) + return -ENXIO; + + if (mask) { + list_for_each_entry(temp, &priv->base.outp, head) { + if ((temp->info.hasht == type) && + (temp->info.hashm & mask) == mask) { + outp = temp; + break; + } + } + if (outp == NULL) + return -ENXIO; + } + + switch (mthd) { + case NV50_DISP_SCANOUTPOS: + return impl->head.scanoutpos(object, priv, data, size, head); + default: + break; + } + + switch (mthd * !!outp) { + case NV50_DISP_MTHD_V1_DAC_PWR: + return priv->dac.power(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_DAC_LOAD: + return priv->dac.sense(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_SOR_PWR: + return priv->sor.power(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_SOR_HDA_ELD: + if (!priv->sor.hda_eld) + return -ENODEV; + return priv->sor.hda_eld(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_SOR_HDMI_PWR: + if (!priv->sor.hdmi) + return -ENODEV; + return priv->sor.hdmi(object, priv, data, size, head, outp); + case NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT: { + union { + struct nv50_disp_sor_lvds_script_v0 v0; + } *args = data; + nv_ioctl(object, "disp sor lvds script size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor lvds script " + "vers %d name %04x\n", + args->v0.version, args->v0.script); + priv->sor.lvdsconf = args->v0.script; + return 0; + } else + return ret; + } + break; + case NV50_DISP_MTHD_V1_SOR_DP_PWR: { + struct nvkm_output_dp *outpdp = (void *)outp; + union { + struct nv50_disp_sor_dp_pwr_v0 v0; + } *args = data; + nv_ioctl(object, "disp sor dp pwr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor dp pwr vers %d state %d\n", + args->v0.version, args->v0.state); + if (args->v0.state == 0) { + nvkm_notify_put(&outpdp->irq); + ((struct nvkm_output_dp_impl *)nv_oclass(outp)) + ->lnk_pwr(outpdp, 0); + atomic_set(&outpdp->lt.done, 0); + return 0; + } else + if (args->v0.state != 0) { + nvkm_output_dp_train(&outpdp->base, 0, true); + return 0; + } + } else + return ret; + } + break; + case NV50_DISP_MTHD_V1_PIOR_PWR: + if (!priv->pior.power) + return -ENODEV; + return priv->pior.power(object, priv, data, size, head, outp); + default: + break; + } + + return -EINVAL; } -static int +int nv50_disp_base_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -856,14 +1042,11 @@ nv50_disp_base_ctor(struct nouveau_object *parent, if (ret) return ret; - priv->base.vblank->priv = priv; - priv->base.vblank->enable = nv50_disp_base_vblank_enable; - priv->base.vblank->disable = nv50_disp_base_vblank_disable; return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0, &base->ramht); } -static void +void nv50_disp_base_dtor(struct nouveau_object *object) { struct nv50_disp_base *base = (void *)object; @@ -958,34 +1141,23 @@ nv50_disp_base_ofuncs = { .dtor = nv50_disp_base_dtor, .init = nv50_disp_base_init, .fini = nv50_disp_base_fini, -}; - -static struct nouveau_omthds -nv50_disp_base_omthds[] = { - { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, - {}, + .mthd = nv50_disp_base_mthd, + .ntfy = nouveau_disp_ntfy, }; static struct nouveau_oclass nv50_disp_base_oclass[] = { - { NV50_DISP_CLASS, &nv50_disp_base_ofuncs, nv50_disp_base_omthds }, + { NV50_DISP, &nv50_disp_base_ofuncs }, {} }; static struct nouveau_oclass nv50_disp_sclass[] = { - { NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, - { NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs }, - { NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs }, - { NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs }, - { NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs }, + { NV50_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, + { NV50_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, + { NV50_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, + { NV50_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, + { NV50_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, {} }; @@ -1005,7 +1177,7 @@ nv50_disp_data_ctor(struct nouveau_object *parent, int ret = -EBUSY; /* no context needed for channel objects... */ - if (nv_mclass(parent) != NV_DEVICE_CLASS) { + if (nv_mclass(parent) != NV_DEVICE) { atomic_inc(&parent->refcount); *pobject = parent; return 1; @@ -1040,6 +1212,27 @@ nv50_disp_cclass = { * Display engine implementation ******************************************************************************/ +static void +nv50_disp_vblank_fini(struct nvkm_event *event, int type, int head) +{ + struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank); + nv_mask(disp, 0x61002c, (4 << head), 0); +} + +static void +nv50_disp_vblank_init(struct nvkm_event *event, int type, int head) +{ + struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank); + nv_mask(disp, 0x61002c, (4 << head), (4 << head)); +} + +const struct nvkm_event_func +nv50_disp_vblank_func = { + .ctor = nouveau_disp_vblank_ctor, + .init = nv50_disp_vblank_init, + .fini = nv50_disp_vblank_fini, +}; + static const struct nouveau_enum nv50_disp_intr_error_type[] = { { 3, "ILLEGAL_MTHD" }, @@ -1381,7 +1574,7 @@ nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, int TU, VTUi, VTUf, VTUa; u64 link_data_rate, link_ratio, unk; u32 best_diff = 64 * symbol; - u32 link_nr, link_bw, bits, r; + u32 link_nr, link_bw, bits; /* calculate packed data rate for each lane */ if (dpctrl > 0x00030000) link_nr = 4; @@ -1401,7 +1594,7 @@ nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, /* calculate ratio of packed data rate to link symbol rate */ link_ratio = link_data_rate * symbol; - r = do_div(link_ratio, link_bw); + do_div(link_ratio, link_bw); for (TU = 64; TU >= 32; TU--) { /* calculate average number of valid symbols in each TU */ @@ -1462,8 +1655,8 @@ nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, /* XXX close to vbios numbers, but not right */ unk = (symbol - link_ratio) * bestTU; unk *= link_ratio; - r = do_div(unk, symbol); - r = do_div(unk, symbol); + do_div(unk, symbol); + do_div(unk, symbol); unk += 6; nv_mask(priv, 0x61c10c + loff, 0x000001fc, bestTU << 2); @@ -1654,13 +1847,13 @@ nv50_disp_intr(struct nouveau_subdev *subdev) } if (intr1 & 0x00000004) { - nouveau_event_trigger(priv->base.vblank, 1, 0); + nouveau_disp_vblank(&priv->base, 0); nv_wr32(priv, 0x610024, 0x00000004); intr1 &= ~0x00000004; } if (intr1 & 0x00000008) { - nouveau_event_trigger(priv->base.vblank, 1, 1); + nouveau_disp_vblank(&priv->base, 1); nv_wr32(priv, 0x610024, 0x00000008); intr1 &= ~0x00000008; } @@ -1718,9 +1911,11 @@ nv50_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nv50_disp_vblank_func, .base.outp = nv50_disp_outp_sclass, .mthd.core = &nv50_disp_mast_mthd_chan, .mthd.base = &nv50_disp_sync_mthd_chan, .mthd.ovly = &nv50_disp_ovly_mthd_chan, .mthd.prev = 0x000004, + .head.scanoutpos = nv50_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index 1a886472b6f5..8ab14461f70c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -14,15 +14,10 @@ #include "outp.h" #include "outpdp.h" -struct nv50_disp_impl { - struct nouveau_disp_impl base; - struct { - const struct nv50_disp_mthd_chan *core; - const struct nv50_disp_mthd_chan *base; - const struct nv50_disp_mthd_chan *ovly; - int prev; - } mthd; -}; +#define NV50_DISP_MTHD_ struct nouveau_object *object, \ + struct nv50_disp_priv *priv, void *data, u32 size +#define NV50_DISP_MTHD_V0 NV50_DISP_MTHD_, int head +#define NV50_DISP_MTHD_V1 NV50_DISP_MTHD_, int head, struct nvkm_output *outp struct nv50_disp_priv { struct nouveau_disp base; @@ -36,44 +31,52 @@ struct nv50_disp_priv { } head; struct { int nr; - int (*power)(struct nv50_disp_priv *, int dac, u32 data); - int (*sense)(struct nv50_disp_priv *, int dac, u32 load); + int (*power)(NV50_DISP_MTHD_V1); + int (*sense)(NV50_DISP_MTHD_V1); } dac; struct { int nr; - int (*power)(struct nv50_disp_priv *, int sor, u32 data); - int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); - int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); + int (*power)(NV50_DISP_MTHD_V1); + int (*hda_eld)(NV50_DISP_MTHD_V1); + int (*hdmi)(NV50_DISP_MTHD_V1); u32 lvdsconf; } sor; struct { int nr; - int (*power)(struct nv50_disp_priv *, int ext, u32 data); + int (*power)(NV50_DISP_MTHD_V1); u8 type[3]; } pior; }; -#define HEAD_MTHD(n) (n), (n) + 0x03 - -int nv50_disp_base_scanoutpos(struct nouveau_object *, u32, void *, u32); +struct nv50_disp_impl { + struct nouveau_disp_impl base; + struct { + const struct nv50_disp_mthd_chan *core; + const struct nv50_disp_mthd_chan *base; + const struct nv50_disp_mthd_chan *ovly; + int prev; + } mthd; + struct { + int (*scanoutpos)(NV50_DISP_MTHD_V0); + } head; +}; -#define DAC_MTHD(n) (n), (n) + 0x03 +int nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0); +int nv50_disp_base_mthd(struct nouveau_object *, u32, void *, u32); -int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); -int nv50_dac_power(struct nv50_disp_priv *, int, u32); -int nv50_dac_sense(struct nv50_disp_priv *, int, u32); +int nvd0_disp_base_scanoutpos(NV50_DISP_MTHD_V0); -#define SOR_MTHD(n) (n), (n) + 0x3f +int nv50_dac_power(NV50_DISP_MTHD_V1); +int nv50_dac_sense(NV50_DISP_MTHD_V1); -int nva3_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); -int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); +int nva3_hda_eld(NV50_DISP_MTHD_V1); +int nvd0_hda_eld(NV50_DISP_MTHD_V1); -int nv84_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); -int nva3_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); -int nvd0_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); +int nv84_hdmi_ctrl(NV50_DISP_MTHD_V1); +int nva3_hdmi_ctrl(NV50_DISP_MTHD_V1); +int nvd0_hdmi_ctrl(NV50_DISP_MTHD_V1); -int nv50_sor_mthd(struct nouveau_object *, u32, void *, u32); -int nv50_sor_power(struct nv50_disp_priv *, int, u32); +int nv50_sor_power(NV50_DISP_MTHD_V1); int nv94_sor_dp_train_init(struct nv50_disp_priv *, int, int, int, u16, u16, u32, struct dcb_output *); @@ -93,10 +96,7 @@ int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, int nvd0_sor_dp_drvctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, struct dcb_output *); -#define PIOR_MTHD(n) (n), (n) + 0x03 - -int nv50_pior_mthd(struct nouveau_object *, u32, void *, u32); -int nv50_pior_power(struct nv50_disp_priv *, int, u32); +int nv50_pior_power(NV50_DISP_MTHD_V1); struct nv50_disp_base { struct nouveau_parent base; @@ -104,14 +104,19 @@ struct nv50_disp_base { u32 chan; }; +struct nv50_disp_chan_impl { + struct nouveau_ofuncs base; + int chid; + int (*attach)(struct nouveau_object *, struct nouveau_object *, u32); + void (*detach)(struct nouveau_object *, int); +}; + struct nv50_disp_chan { struct nouveau_namedb base; int chid; }; -int nv50_disp_chan_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, int, void **); -void nv50_disp_chan_destroy(struct nv50_disp_chan *); +int nv50_disp_chan_map(struct nouveau_object *, u64 *, u32 *); u32 nv50_disp_chan_rd32(struct nouveau_object *, u64); void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32); @@ -120,20 +125,20 @@ void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32); #define nv50_disp_chan_fini(a,b) \ nouveau_namedb_fini(&(a)->base, (b)) -int nv50_disp_dmac_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, u32, int, int, void **); -void nv50_disp_dmac_dtor(struct nouveau_object *); - struct nv50_disp_dmac { struct nv50_disp_chan base; struct nouveau_dmaobj *pushdma; u32 push; }; +void nv50_disp_dmac_dtor(struct nouveau_object *); + struct nv50_disp_pioc { struct nv50_disp_chan base; }; +void nv50_disp_pioc_dtor(struct nouveau_object *); + struct nv50_disp_mthd_list { u32 mthd; u32 addr; @@ -154,47 +159,67 @@ struct nv50_disp_mthd_chan { } data[]; }; -extern struct nouveau_ofuncs nv50_disp_mast_ofuncs; +extern struct nv50_disp_chan_impl nv50_disp_mast_ofuncs; +int nv50_disp_mast_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_base; extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_sor; extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_pior; -extern struct nouveau_ofuncs nv50_disp_sync_ofuncs; +extern struct nv50_disp_chan_impl nv50_disp_sync_ofuncs; +int nv50_disp_sync_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); extern const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image; -extern struct nouveau_ofuncs nv50_disp_ovly_ofuncs; +extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs; +int nv50_disp_ovly_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base; -extern struct nouveau_ofuncs nv50_disp_oimm_ofuncs; -extern struct nouveau_ofuncs nv50_disp_curs_ofuncs; +extern struct nv50_disp_chan_impl nv50_disp_oimm_ofuncs; +int nv50_disp_oimm_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +extern struct nv50_disp_chan_impl nv50_disp_curs_ofuncs; +int nv50_disp_curs_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); extern struct nouveau_ofuncs nv50_disp_base_ofuncs; +int nv50_disp_base_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void nv50_disp_base_dtor(struct nouveau_object *); +extern struct nouveau_omthds nv50_disp_base_omthds[]; extern struct nouveau_oclass nv50_disp_cclass; void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head, const struct nv50_disp_mthd_chan *); void nv50_disp_intr_supervisor(struct work_struct *); void nv50_disp_intr(struct nouveau_subdev *); +extern const struct nvkm_event_func nv50_disp_vblank_func; extern const struct nv50_disp_mthd_chan nv84_disp_mast_mthd_chan; extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_dac; extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_head; extern const struct nv50_disp_mthd_chan nv84_disp_sync_mthd_chan; extern const struct nv50_disp_mthd_chan nv84_disp_ovly_mthd_chan; -extern struct nouveau_omthds nv84_disp_base_omthds[]; extern const struct nv50_disp_mthd_chan nv94_disp_mast_mthd_chan; -extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs; +extern struct nv50_disp_chan_impl nvd0_disp_mast_ofuncs; extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_base; extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_dac; extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_sor; extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_pior; -extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs; -extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs; +extern struct nv50_disp_chan_impl nvd0_disp_sync_ofuncs; +extern struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs; extern const struct nv50_disp_mthd_chan nvd0_disp_sync_mthd_chan; -extern struct nouveau_ofuncs nvd0_disp_oimm_ofuncs; -extern struct nouveau_ofuncs nvd0_disp_curs_ofuncs; -extern struct nouveau_omthds nvd0_disp_base_omthds[]; +extern struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs; +extern struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs; extern struct nouveau_ofuncs nvd0_disp_base_ofuncs; extern struct nouveau_oclass nvd0_disp_cclass; void nvd0_disp_intr_supervisor(struct work_struct *); void nvd0_disp_intr(struct nouveau_subdev *); +extern const struct nvkm_event_func nvd0_disp_vblank_func; extern const struct nv50_disp_mthd_chan nve0_disp_mast_mthd_chan; extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 1cc62e434683..788ced1b6182 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -204,31 +204,17 @@ nv84_disp_ovly_mthd_chan = { static struct nouveau_oclass nv84_disp_sclass[] = { - { NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, - { NV84_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs }, - { NV84_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs }, - { NV84_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs }, - { NV84_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs }, + { G82_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, + { G82_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, + { G82_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, + { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, + { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, {} }; -struct nouveau_omthds -nv84_disp_base_omthds[] = { - { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, - {}, -}; - static struct nouveau_oclass nv84_disp_base_oclass[] = { - { NV84_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds }, + { G82_DISP, &nv50_disp_base_ofuncs }, {} }; @@ -276,9 +262,11 @@ nv84_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nv50_disp_vblank_func, .base.outp = nv50_disp_outp_sclass, .mthd.core = &nv84_disp_mast_mthd_chan, .mthd.base = &nv84_disp_sync_mthd_chan, .mthd.ovly = &nv84_disp_ovly_mthd_chan, .mthd.prev = 0x000004, + .head.scanoutpos = nv50_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index 4f718a9f5aef..fa79de906eae 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -63,32 +63,17 @@ nv94_disp_mast_mthd_chan = { static struct nouveau_oclass nv94_disp_sclass[] = { - { NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, - { NV94_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs }, - { NV94_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs }, - { NV94_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs }, - { NV94_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs }, + { GT206_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, + { GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, + { GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, + { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, + { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, {} }; -static struct nouveau_omthds -nv94_disp_base_omthds[] = { - { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, - {}, -}; - static struct nouveau_oclass nv94_disp_base_oclass[] = { - { NV94_DISP_CLASS, &nv50_disp_base_ofuncs, nv94_disp_base_omthds }, + { GT206_DISP, &nv50_disp_base_ofuncs }, {} }; @@ -143,9 +128,11 @@ nv94_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nv50_disp_vblank_func, .base.outp = nv94_disp_outp_sclass, .mthd.core = &nv94_disp_mast_mthd_chan, .mthd.base = &nv84_disp_sync_mthd_chan, .mthd.ovly = &nv84_disp_ovly_mthd_chan, .mthd.prev = 0x000004, + .head.scanoutpos = nv50_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c index 6237a9a36f70..7af15f5d48dc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -80,17 +80,17 @@ nva0_disp_ovly_mthd_chan = { static struct nouveau_oclass nva0_disp_sclass[] = { - { NVA0_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, - { NVA0_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs }, - { NVA0_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs }, - { NVA0_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs }, - { NVA0_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs }, + { GT200_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, + { GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, + { GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, + { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, + { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, {} }; static struct nouveau_oclass nva0_disp_base_oclass[] = { - { NVA0_DISP_CLASS, &nv50_disp_base_ofuncs, nv84_disp_base_omthds }, + { GT200_DISP, &nv50_disp_base_ofuncs }, {} }; @@ -138,9 +138,11 @@ nva0_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nv50_disp_vblank_func, .base.outp = nv50_disp_outp_sclass, .mthd.core = &nv84_disp_mast_mthd_chan, .mthd.base = &nv84_disp_sync_mthd_chan, .mthd.ovly = &nva0_disp_ovly_mthd_chan, .mthd.prev = 0x000004, + .head.scanoutpos = nv50_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index 019124d4782b..6bd39448f8da 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -35,33 +35,17 @@ static struct nouveau_oclass nva3_disp_sclass[] = { - { NVA3_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, - { NVA3_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs }, - { NVA3_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs }, - { NVA3_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs }, - { NVA3_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs }, + { GT214_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, + { GT214_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, + { GT214_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, + { GT214_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, + { GT214_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, {} }; -static struct nouveau_omthds -nva3_disp_base_omthds[] = { - { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nv50_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, - { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, - {}, -}; - static struct nouveau_oclass nva3_disp_base_oclass[] = { - { NVA3_DISP_CLASS, &nv50_disp_base_ofuncs, nva3_disp_base_omthds }, + { GT214_DISP, &nv50_disp_base_ofuncs }, {} }; @@ -110,9 +94,11 @@ nva3_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nv50_disp_vblank_func, .base.outp = nv94_disp_outp_sclass, .mthd.core = &nv94_disp_mast_mthd_chan, .mthd.base = &nv84_disp_sync_mthd_chan, .mthd.ovly = &nv84_disp_ovly_mthd_chan, .mthd.prev = 0x000004, + .head.scanoutpos = nv50_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index fa30d8196f35..a4bb3c774ee1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -23,9 +23,11 @@ */ #include <core/object.h> +#include <core/client.h> #include <core/parent.h> #include <core/handle.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <engine/disp.h> @@ -265,30 +267,6 @@ nvd0_disp_mast_mthd_chan = { }; static int -nvd0_disp_mast_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_display_mast_class *args = data; - struct nv50_disp_dmac *mast; - int ret; - - if (size < sizeof(*args)) - return -EINVAL; - - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, - 0, sizeof(*mast), (void **)&mast); - *pobject = nv_object(mast); - if (ret) - return ret; - - nv_parent(mast)->object_attach = nvd0_disp_dmac_object_attach; - nv_parent(mast)->object_detach = nvd0_disp_dmac_object_detach; - return 0; -} - -static int nvd0_disp_mast_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; @@ -342,14 +320,18 @@ nvd0_disp_mast_fini(struct nouveau_object *object, bool suspend) return nv50_disp_chan_fini(&mast->base, suspend); } -struct nouveau_ofuncs +struct nv50_disp_chan_impl nvd0_disp_mast_ofuncs = { - .ctor = nvd0_disp_mast_ctor, - .dtor = nv50_disp_dmac_dtor, - .init = nvd0_disp_mast_init, - .fini = nvd0_disp_mast_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_mast_ctor, + .base.dtor = nv50_disp_dmac_dtor, + .base.init = nvd0_disp_mast_init, + .base.fini = nvd0_disp_mast_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 0, + .attach = nvd0_disp_dmac_object_attach, + .detach = nvd0_disp_dmac_object_detach, }; /******************************************************************************* @@ -431,40 +413,18 @@ nvd0_disp_sync_mthd_chan = { } }; -static int -nvd0_disp_sync_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_display_sync_class *args = data; - struct nv50_disp_priv *priv = (void *)engine; - struct nv50_disp_dmac *dmac; - int ret; - - if (size < sizeof(*args) || args->head >= priv->head.nr) - return -EINVAL; - - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, - 1 + args->head, sizeof(*dmac), - (void **)&dmac); - *pobject = nv_object(dmac); - if (ret) - return ret; - - nv_parent(dmac)->object_attach = nvd0_disp_dmac_object_attach; - nv_parent(dmac)->object_detach = nvd0_disp_dmac_object_detach; - return 0; -} - -struct nouveau_ofuncs +struct nv50_disp_chan_impl nvd0_disp_sync_ofuncs = { - .ctor = nvd0_disp_sync_ctor, - .dtor = nv50_disp_dmac_dtor, - .init = nvd0_disp_dmac_init, - .fini = nvd0_disp_dmac_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_sync_ctor, + .base.dtor = nv50_disp_dmac_dtor, + .base.init = nvd0_disp_dmac_init, + .base.fini = nvd0_disp_dmac_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 1, + .attach = nvd0_disp_dmac_object_attach, + .detach = nvd0_disp_dmac_object_detach, }; /******************************************************************************* @@ -533,40 +493,18 @@ nvd0_disp_ovly_mthd_chan = { } }; -static int -nvd0_disp_ovly_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_display_ovly_class *args = data; - struct nv50_disp_priv *priv = (void *)engine; - struct nv50_disp_dmac *dmac; - int ret; - - if (size < sizeof(*args) || args->head >= priv->head.nr) - return -EINVAL; - - ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf, - 5 + args->head, sizeof(*dmac), - (void **)&dmac); - *pobject = nv_object(dmac); - if (ret) - return ret; - - nv_parent(dmac)->object_attach = nvd0_disp_dmac_object_attach; - nv_parent(dmac)->object_detach = nvd0_disp_dmac_object_detach; - return 0; -} - -struct nouveau_ofuncs +struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs = { - .ctor = nvd0_disp_ovly_ctor, - .dtor = nv50_disp_dmac_dtor, - .init = nvd0_disp_dmac_init, - .fini = nvd0_disp_dmac_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_ovly_ctor, + .base.dtor = nv50_disp_dmac_dtor, + .base.init = nvd0_disp_dmac_init, + .base.fini = nvd0_disp_dmac_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 5, + .attach = nvd0_disp_dmac_object_attach, + .detach = nvd0_disp_dmac_object_detach, }; /******************************************************************************* @@ -574,23 +512,6 @@ nvd0_disp_ovly_ofuncs = { ******************************************************************************/ static int -nvd0_disp_pioc_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, int chid, - int length, void **pobject) -{ - return nv50_disp_chan_create_(parent, engine, oclass, chid, - length, pobject); -} - -static void -nvd0_disp_pioc_dtor(struct nouveau_object *object) -{ - struct nv50_disp_pioc *pioc = (void *)object; - nv50_disp_chan_destroy(&pioc->base); -} - -static int nvd0_disp_pioc_init(struct nouveau_object *object) { struct nv50_disp_priv *priv = (void *)object->engine; @@ -643,152 +564,68 @@ nvd0_disp_pioc_fini(struct nouveau_object *object, bool suspend) * EVO immediate overlay channel objects ******************************************************************************/ -static int -nvd0_disp_oimm_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_display_oimm_class *args = data; - struct nv50_disp_priv *priv = (void *)engine; - struct nv50_disp_pioc *pioc; - int ret; - - if (size < sizeof(*args) || args->head >= priv->head.nr) - return -EINVAL; - - ret = nvd0_disp_pioc_create_(parent, engine, oclass, 9 + args->head, - sizeof(*pioc), (void **)&pioc); - *pobject = nv_object(pioc); - if (ret) - return ret; - - return 0; -} - -struct nouveau_ofuncs +struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs = { - .ctor = nvd0_disp_oimm_ctor, - .dtor = nvd0_disp_pioc_dtor, - .init = nvd0_disp_pioc_init, - .fini = nvd0_disp_pioc_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_oimm_ctor, + .base.dtor = nv50_disp_pioc_dtor, + .base.init = nvd0_disp_pioc_init, + .base.fini = nvd0_disp_pioc_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 9, }; /******************************************************************************* * EVO cursor channel objects ******************************************************************************/ -static int -nvd0_disp_curs_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_display_curs_class *args = data; - struct nv50_disp_priv *priv = (void *)engine; - struct nv50_disp_pioc *pioc; - int ret; - - if (size < sizeof(*args) || args->head >= priv->head.nr) - return -EINVAL; - - ret = nvd0_disp_pioc_create_(parent, engine, oclass, 13 + args->head, - sizeof(*pioc), (void **)&pioc); - *pobject = nv_object(pioc); - if (ret) - return ret; - - return 0; -} - -struct nouveau_ofuncs +struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs = { - .ctor = nvd0_disp_curs_ctor, - .dtor = nvd0_disp_pioc_dtor, - .init = nvd0_disp_pioc_init, - .fini = nvd0_disp_pioc_fini, - .rd32 = nv50_disp_chan_rd32, - .wr32 = nv50_disp_chan_wr32, + .base.ctor = nv50_disp_curs_ctor, + .base.dtor = nv50_disp_pioc_dtor, + .base.init = nvd0_disp_pioc_init, + .base.fini = nvd0_disp_pioc_fini, + .base.map = nv50_disp_chan_map, + .base.rd32 = nv50_disp_chan_rd32, + .base.wr32 = nv50_disp_chan_wr32, + .chid = 13, }; /******************************************************************************* * Base display object ******************************************************************************/ -static int -nvd0_disp_base_scanoutpos(struct nouveau_object *object, u32 mthd, - void *data, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - struct nv04_display_scanoutpos *args = data; - const int head = (mthd & NV50_DISP_MTHD_HEAD); - u32 blanke, blanks, total; - - if (size < sizeof(*args) || head >= priv->head.nr) - return -EINVAL; - - total = nv_rd32(priv, 0x640414 + (head * 0x300)); - blanke = nv_rd32(priv, 0x64041c + (head * 0x300)); - blanks = nv_rd32(priv, 0x640420 + (head * 0x300)); - - args->vblanke = (blanke & 0xffff0000) >> 16; - args->hblanke = (blanke & 0x0000ffff); - args->vblanks = (blanks & 0xffff0000) >> 16; - args->hblanks = (blanks & 0x0000ffff); - args->vtotal = ( total & 0xffff0000) >> 16; - args->htotal = ( total & 0x0000ffff); - - args->time[0] = ktime_to_ns(ktime_get()); - args->vline = nv_rd32(priv, 0x616340 + (head * 0x800)) & 0xffff; - args->time[1] = ktime_to_ns(ktime_get()); /* vline read locks hline */ - args->hline = nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff; - return 0; -} - -static void -nvd0_disp_base_vblank_enable(struct nouveau_event *event, int type, int head) -{ - nv_mask(event->priv, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000001); -} - -static void -nvd0_disp_base_vblank_disable(struct nouveau_event *event, int type, int head) +int +nvd0_disp_base_scanoutpos(NV50_DISP_MTHD_V0) { - nv_mask(event->priv, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000); -} - -static int -nvd0_disp_base_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_disp_priv *priv = (void *)engine; - struct nv50_disp_base *base; + const u32 total = nv_rd32(priv, 0x640414 + (head * 0x300)); + const u32 blanke = nv_rd32(priv, 0x64041c + (head * 0x300)); + const u32 blanks = nv_rd32(priv, 0x640420 + (head * 0x300)); + union { + struct nv04_disp_scanoutpos_v0 v0; + } *args = data; int ret; - ret = nouveau_parent_create(parent, engine, oclass, 0, - priv->sclass, 0, &base); - *pobject = nv_object(base); - if (ret) + nv_ioctl(object, "disp scanoutpos size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version); + args->v0.vblanke = (blanke & 0xffff0000) >> 16; + args->v0.hblanke = (blanke & 0x0000ffff); + args->v0.vblanks = (blanks & 0xffff0000) >> 16; + args->v0.hblanks = (blanks & 0x0000ffff); + args->v0.vtotal = ( total & 0xffff0000) >> 16; + args->v0.htotal = ( total & 0x0000ffff); + args->v0.time[0] = ktime_to_ns(ktime_get()); + args->v0.vline = /* vline read locks hline */ + nv_rd32(priv, 0x616340 + (head * 0x800)) & 0xffff; + args->v0.time[1] = ktime_to_ns(ktime_get()); + args->v0.hline = + nv_rd32(priv, 0x616344 + (head * 0x800)) & 0xffff; + } else return ret; - priv->base.vblank->priv = priv; - priv->base.vblank->enable = nvd0_disp_base_vblank_enable; - priv->base.vblank->disable = nvd0_disp_base_vblank_disable; - - return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0, - &base->ramht); -} - -static void -nvd0_disp_base_dtor(struct nouveau_object *object) -{ - struct nv50_disp_base *base = (void *)object; - nouveau_ramht_ref(NULL, &base->ramht); - nouveau_parent_destroy(&base->base); + return 0; } static int @@ -874,41 +711,27 @@ nvd0_disp_base_fini(struct nouveau_object *object, bool suspend) struct nouveau_ofuncs nvd0_disp_base_ofuncs = { - .ctor = nvd0_disp_base_ctor, - .dtor = nvd0_disp_base_dtor, + .ctor = nv50_disp_base_ctor, + .dtor = nv50_disp_base_dtor, .init = nvd0_disp_base_init, .fini = nvd0_disp_base_fini, -}; - -struct nouveau_omthds -nvd0_disp_base_omthds[] = { - { HEAD_MTHD(NV50_DISP_SCANOUTPOS) , nvd0_disp_base_scanoutpos }, - { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, - { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, - { SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd }, - { SOR_MTHD(NV94_DISP_SOR_DP_PWR) , nv50_sor_mthd }, - { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, - { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_TMDS_PWR) , nv50_pior_mthd }, - { PIOR_MTHD(NV50_DISP_PIOR_DP_PWR) , nv50_pior_mthd }, - {}, + .mthd = nv50_disp_base_mthd, + .ntfy = nouveau_disp_ntfy, }; static struct nouveau_oclass nvd0_disp_base_oclass[] = { - { NVD0_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds }, + { GF110_DISP, &nvd0_disp_base_ofuncs }, {} }; static struct nouveau_oclass nvd0_disp_sclass[] = { - { NVD0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs }, - { NVD0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs }, - { NVD0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs }, - { NVD0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs }, - { NVD0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs }, + { GF110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, + { GF110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, + { GF110_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, + { GF110_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, + { GF110_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, {} }; @@ -916,6 +739,27 @@ nvd0_disp_sclass[] = { * Display engine implementation ******************************************************************************/ +static void +nvd0_disp_vblank_init(struct nvkm_event *event, int type, int head) +{ + struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank); + nv_mask(disp, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000001); +} + +static void +nvd0_disp_vblank_fini(struct nvkm_event *event, int type, int head) +{ + struct nouveau_disp *disp = container_of(event, typeof(*disp), vblank); + nv_mask(disp, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000); +} + +const struct nvkm_event_func +nvd0_disp_vblank_func = { + .ctor = nouveau_disp_vblank_ctor, + .init = nvd0_disp_vblank_init, + .fini = nvd0_disp_vblank_fini, +}; + static struct nvkm_output * exec_lookup(struct nv50_disp_priv *priv, int head, int or, u32 ctrl, u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, @@ -1343,7 +1187,7 @@ nvd0_disp_intr(struct nouveau_subdev *subdev) if (mask & intr) { u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800)); if (stat & 0x00000001) - nouveau_event_trigger(priv->base.vblank, 1, i); + nouveau_disp_vblank(&priv->base, i); nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0); nv_rd32(priv, 0x6100c0 + (i * 0x800)); } @@ -1396,9 +1240,11 @@ nvd0_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nvd0_disp_vblank_func, .base.outp = nvd0_disp_outp_sclass, .mthd.core = &nvd0_disp_mast_mthd_chan, .mthd.base = &nvd0_disp_sync_mthd_chan, .mthd.ovly = &nvd0_disp_ovly_mthd_chan, .mthd.prev = -0x020000, + .head.scanoutpos = nvd0_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c index 11328e3f5df1..47fef1e398c4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -200,17 +200,17 @@ nve0_disp_ovly_mthd_chan = { static struct nouveau_oclass nve0_disp_sclass[] = { - { NVE0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs }, - { NVE0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs }, - { NVE0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs }, - { NVE0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs }, - { NVE0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs }, + { GK104_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, + { GK104_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, + { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, + { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, + { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, {} }; static struct nouveau_oclass nve0_disp_base_oclass[] = { - { NVE0_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds }, + { GK104_DISP, &nvd0_disp_base_ofuncs }, {} }; @@ -258,9 +258,11 @@ nve0_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nvd0_disp_vblank_func, .base.outp = nvd0_disp_outp_sclass, .mthd.core = &nve0_disp_mast_mthd_chan, .mthd.base = &nvd0_disp_sync_mthd_chan, .mthd.ovly = &nve0_disp_ovly_mthd_chan, .mthd.prev = -0x020000, + .head.scanoutpos = nvd0_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c index 104388081d73..04bda4ac4ed3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c @@ -25,7 +25,7 @@ #include <engine/software.h> #include <engine/disp.h> -#include <core/class.h> +#include <nvif/class.h> #include "nv50.h" @@ -35,17 +35,17 @@ static struct nouveau_oclass nvf0_disp_sclass[] = { - { NVF0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs }, - { NVF0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs }, - { NVF0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs }, - { NVF0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs }, - { NVF0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs }, + { GK110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, + { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, + { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, + { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, + { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, {} }; static struct nouveau_oclass nvf0_disp_base_oclass[] = { - { NVF0_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds }, + { GK110_DISP, &nvd0_disp_base_ofuncs }, {} }; @@ -93,9 +93,11 @@ nvf0_disp_oclass = &(struct nv50_disp_impl) { .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, + .base.vblank = &nvd0_disp_vblank_func, .base.outp = nvd0_disp_outp_sclass, .mthd.core = &nve0_disp_mast_mthd_chan, .mthd.base = &nvd0_disp_sync_mthd_chan, .mthd.ovly = &nve0_disp_ovly_mthd_chan, .mthd.prev = -0x020000, + .head.scanoutpos = nvd0_disp_base_scanoutpos, }.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outp.c index ad9ba7ccec7f..a5ff00a9cedc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outp.c @@ -78,6 +78,7 @@ nvkm_output_create_(struct nouveau_object *parent, outp->info = *dcbE; outp->index = index; + outp->or = ffs(outp->info.or) - 1; DBG("type %02x loc %d or %d link %d con %x edid %x bus %d head %x\n", dcbE->type, dcbE->location, dcbE->or, dcbE->type >= 2 ? diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.h b/drivers/gpu/drm/nouveau/core/engine/disp/outp.h index bc76fbf85710..187f435ad0e2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/outp.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outp.h @@ -9,6 +9,7 @@ struct nvkm_output { struct dcb_output info; int index; + int or; struct nouveau_i2c_port *port; struct nouveau_i2c_port *edid; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c index eb2d7789555d..6f6e2a898270 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c @@ -22,6 +22,9 @@ * Authors: Ben Skeggs */ +#include <core/os.h> +#include <nvif/event.h> + #include <subdev/i2c.h> #include "outpdp.h" @@ -86,7 +89,7 @@ done: atomic_set(&outp->lt.done, 0); schedule_work(&outp->lt.work); } else { - nouveau_event_get(outp->irq); + nvkm_notify_get(&outp->irq); } if (wait) { @@ -133,46 +136,59 @@ nvkm_output_dp_detect(struct nvkm_output_dp *outp) } } -static void -nvkm_output_dp_service_work(struct work_struct *work) +static int +nvkm_output_dp_hpd(struct nvkm_notify *notify) { - struct nvkm_output_dp *outp = container_of(work, typeof(*outp), work); - struct nouveau_disp *disp = nouveau_disp(outp); - int type = atomic_xchg(&outp->pending, 0); - u32 send = 0; - - if (type & (NVKM_I2C_PLUG | NVKM_I2C_UNPLUG)) { - nvkm_output_dp_detect(outp); - if (type & NVKM_I2C_UNPLUG) - send |= NVKM_HPD_UNPLUG; - if (type & NVKM_I2C_PLUG) - send |= NVKM_HPD_PLUG; - nouveau_event_get(outp->base.conn->hpd.event); - } - - if (type & NVKM_I2C_IRQ) { - nvkm_output_dp_train(&outp->base, 0, true); - send |= NVKM_HPD_IRQ; + struct nvkm_connector *conn = container_of(notify, typeof(*conn), hpd); + struct nvkm_output_dp *outp; + struct nouveau_disp *disp = nouveau_disp(conn); + const struct nvkm_i2c_ntfy_rep *line = notify->data; + struct nvif_notify_conn_rep_v0 rep = {}; + + list_for_each_entry(outp, &disp->outp, base.head) { + if (outp->base.conn == conn && + outp->info.type == DCB_OUTPUT_DP) { + DBG("HPD: %d\n", line->mask); + nvkm_output_dp_detect(outp); + + if (line->mask & NVKM_I2C_UNPLUG) + rep.mask |= NVIF_NOTIFY_CONN_V0_UNPLUG; + if (line->mask & NVKM_I2C_PLUG) + rep.mask |= NVIF_NOTIFY_CONN_V0_PLUG; + + nvkm_event_send(&disp->hpd, rep.mask, conn->index, + &rep, sizeof(rep)); + return NVKM_NOTIFY_KEEP; + } } - nouveau_event_trigger(disp->hpd, send, outp->base.info.connector); + WARN_ON(1); + return NVKM_NOTIFY_DROP; } static int -nvkm_output_dp_service(void *data, u32 type, int index) +nvkm_output_dp_irq(struct nvkm_notify *notify) { - struct nvkm_output_dp *outp = data; - DBG("HPD: %d\n", type); - atomic_or(type, &outp->pending); - schedule_work(&outp->work); - return NVKM_EVENT_DROP; + struct nvkm_output_dp *outp = container_of(notify, typeof(*outp), irq); + struct nouveau_disp *disp = nouveau_disp(outp); + const struct nvkm_i2c_ntfy_rep *line = notify->data; + struct nvif_notify_conn_rep_v0 rep = { + .mask = NVIF_NOTIFY_CONN_V0_IRQ, + }; + int index = outp->base.info.connector; + + DBG("IRQ: %d\n", line->mask); + nvkm_output_dp_train(&outp->base, 0, true); + + nvkm_event_send(&disp->hpd, rep.mask, index, &rep, sizeof(rep)); + return NVKM_NOTIFY_DROP; } int _nvkm_output_dp_fini(struct nouveau_object *object, bool suspend) { struct nvkm_output_dp *outp = (void *)object; - nouveau_event_put(outp->irq); + nvkm_notify_put(&outp->irq); nvkm_output_dp_enable(outp, false); return nvkm_output_fini(&outp->base, suspend); } @@ -189,7 +205,7 @@ void _nvkm_output_dp_dtor(struct nouveau_object *object) { struct nvkm_output_dp *outp = (void *)object; - nouveau_event_ref(NULL, &outp->irq); + nvkm_notify_fini(&outp->irq); nvkm_output_destroy(&outp->base); } @@ -213,7 +229,7 @@ nvkm_output_dp_create_(struct nouveau_object *parent, if (ret) return ret; - nouveau_event_ref(NULL, &outp->base.conn->hpd.event); + nvkm_notify_fini(&outp->base.conn->hpd); /* access to the aux channel is not optional... */ if (!outp->base.edid) { @@ -238,20 +254,28 @@ nvkm_output_dp_create_(struct nouveau_object *parent, atomic_set(&outp->lt.done, 0); /* link maintenance */ - ret = nouveau_event_new(i2c->ntfy, NVKM_I2C_IRQ, outp->base.edid->index, - nvkm_output_dp_service, outp, &outp->irq); + ret = nvkm_notify_init(&i2c->event, nvkm_output_dp_irq, true, + &(struct nvkm_i2c_ntfy_req) { + .mask = NVKM_I2C_IRQ, + .port = outp->base.edid->index, + }, + sizeof(struct nvkm_i2c_ntfy_req), + sizeof(struct nvkm_i2c_ntfy_rep), + &outp->irq); if (ret) { ERR("error monitoring aux irq event: %d\n", ret); return ret; } - INIT_WORK(&outp->work, nvkm_output_dp_service_work); - /* hotplug detect, replaces gpio-based mechanism with aux events */ - ret = nouveau_event_new(i2c->ntfy, NVKM_I2C_PLUG | NVKM_I2C_UNPLUG, - outp->base.edid->index, - nvkm_output_dp_service, outp, - &outp->base.conn->hpd.event); + ret = nvkm_notify_init(&i2c->event, nvkm_output_dp_hpd, true, + &(struct nvkm_i2c_ntfy_req) { + .mask = NVKM_I2C_PLUG | NVKM_I2C_UNPLUG, + .port = outp->base.edid->index, + }, + sizeof(struct nvkm_i2c_ntfy_req), + sizeof(struct nvkm_i2c_ntfy_rep), + &outp->base.conn->hpd); if (ret) { ERR("error monitoring aux hpd events: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h index ff33ba12cb67..1fac367cc867 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h @@ -12,10 +12,7 @@ struct nvkm_output_dp { struct nvbios_dpout info; u8 version; - struct nouveau_eventh *irq; - struct nouveau_eventh *hpd; - struct work_struct work; - atomic_t pending; + struct nvkm_notify irq; bool present; u8 dpcd[16]; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c index fe0f256f11bf..d00f89a468a7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> @@ -143,38 +144,29 @@ nv50_pior_dp_impl = { *****************************************************************************/ int -nv50_pior_power(struct nv50_disp_priv *priv, int or, u32 data) +nv50_pior_power(NV50_DISP_MTHD_V1) { - const u32 stat = data & NV50_DISP_PIOR_PWR_STATE; - const u32 soff = (or * 0x800); + const u32 soff = outp->or * 0x800; + union { + struct nv50_disp_pior_pwr_v0 v0; + } *args = data; + u32 ctrl, type; + int ret; + + nv_ioctl(object, "disp pior pwr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp pior pwr vers %d state %d type %x\n", + args->v0.version, args->v0.state, args->v0.type); + if (args->v0.type > 0x0f) + return -EINVAL; + ctrl = !!args->v0.state; + type = args->v0.type; + } else + return ret; + nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); - nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | stat); + nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl); nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); + priv->pior.type[outp->or] = type; return 0; } - -int -nv50_pior_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - const u8 type = (mthd & NV50_DISP_PIOR_MTHD_TYPE) >> 12; - const u8 or = (mthd & NV50_DISP_PIOR_MTHD_OR); - u32 *data = args; - int ret; - - if (size < sizeof(u32)) - return -EINVAL; - - mthd &= ~NV50_DISP_PIOR_MTHD_TYPE; - mthd &= ~NV50_DISP_PIOR_MTHD_OR; - switch (mthd) { - case NV50_DISP_PIOR_PWR: - ret = priv->pior.power(priv, or, data[0]); - priv->pior.type[or] = type; - break; - default: - return -EINVAL; - } - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/priv.h b/drivers/gpu/drm/nouveau/core/engine/disp/priv.h index 26e9a42569c7..dbd43ae9df81 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/priv.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/priv.h @@ -11,6 +11,7 @@ struct nouveau_disp_impl { struct nouveau_oclass base; struct nouveau_oclass **outp; struct nouveau_oclass **conn; + const struct nvkm_event_func *vblank; }; #define nouveau_disp_create(p,e,c,h,i,x,d) \ @@ -39,4 +40,8 @@ int _nouveau_disp_fini(struct nouveau_object *, bool); extern struct nouveau_oclass *nvkm_output_oclass; extern struct nouveau_oclass *nvkm_connector_oclass; +int nouveau_disp_vblank_ctor(void *data, u32 size, struct nvkm_notify *); +void nouveau_disp_vblank(struct nouveau_disp *, int head); +int nouveau_disp_ntfy(struct nouveau_object *, u32, struct nvkm_event **); + #endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index 7a1ebdfa9e1b..ddf1760c4400 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> @@ -32,77 +33,26 @@ #include "nv50.h" int -nv50_sor_power(struct nv50_disp_priv *priv, int or, u32 data) +nv50_sor_power(NV50_DISP_MTHD_V1) { - const u32 stat = data & NV50_DISP_SOR_PWR_STATE; - const u32 soff = (or * 0x800); + union { + struct nv50_disp_sor_pwr_v0 v0; + } *args = data; + const u32 soff = outp->or * 0x800; + u32 stat; + int ret; + + nv_ioctl(object, "disp sor pwr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "disp sor pwr vers %d state %d\n", + args->v0.version, args->v0.state); + stat = !!args->v0.state; + } else + return ret; + nv_wait(priv, 0x61c004 + soff, 0x80000000, 0x00000000); nv_mask(priv, 0x61c004 + soff, 0x80000001, 0x80000000 | stat); nv_wait(priv, 0x61c004 + soff, 0x80000000, 0x00000000); nv_wait(priv, 0x61c030 + soff, 0x10000000, 0x00000000); return 0; } - -int -nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) -{ - struct nv50_disp_priv *priv = (void *)object->engine; - const u8 type = (mthd & NV50_DISP_SOR_MTHD_TYPE) >> 12; - const u8 head = (mthd & NV50_DISP_SOR_MTHD_HEAD) >> 3; - const u8 link = (mthd & NV50_DISP_SOR_MTHD_LINK) >> 2; - const u8 or = (mthd & NV50_DISP_SOR_MTHD_OR); - const u16 mask = (0x0100 << head) | (0x0040 << link) | (0x0001 << or); - struct nvkm_output *outp = NULL, *temp; - u32 data; - int ret = -EINVAL; - - if (size < sizeof(u32)) - return -EINVAL; - data = *(u32 *)args; - - list_for_each_entry(temp, &priv->base.outp, head) { - if ((temp->info.hasht & 0xff) == type && - (temp->info.hashm & mask) == mask) { - outp = temp; - break; - } - } - - switch (mthd & ~0x3f) { - case NV50_DISP_SOR_PWR: - ret = priv->sor.power(priv, or, data); - break; - case NVA3_DISP_SOR_HDA_ELD: - ret = priv->sor.hda_eld(priv, or, args, size); - break; - case NV84_DISP_SOR_HDMI_PWR: - ret = priv->sor.hdmi(priv, head, or, data); - break; - case NV50_DISP_SOR_LVDS_SCRIPT: - priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID; - ret = 0; - break; - case NV94_DISP_SOR_DP_PWR: - if (outp) { - struct nvkm_output_dp *outpdp = (void *)outp; - switch (data) { - case NV94_DISP_SOR_DP_PWR_STATE_OFF: - nouveau_event_put(outpdp->irq); - ((struct nvkm_output_dp_impl *)nv_oclass(outp)) - ->lnk_pwr(outpdp, 0); - atomic_set(&outpdp->lt.done, 0); - break; - case NV94_DISP_SOR_DP_PWR_STATE_ON: - nvkm_output_dp_train(&outpdp->base, 0, true); - break; - default: - return -EINVAL; - } - } - break; - default: - BUG_ON(1); - } - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c index 05487cda84a8..39f85d627336 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c index 97f0e9cd3d40..7b7bbc3e459e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c index 5103e88d1877..e1500f77a56a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c @@ -23,98 +23,143 @@ */ #include <core/object.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/fb.h> -#include <engine/dmaobj.h> +#include <subdev/instmem.h> + +#include "priv.h" static int -nouveau_dmaobj_ctor(struct nouveau_object *parent, +nvkm_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent, + struct nouveau_gpuobj **pgpuobj) +{ + const struct nvkm_dmaeng_impl *impl = (void *) + nv_oclass(nv_object(dmaobj)->engine); + int ret = 0; + + if (nv_object(dmaobj) == parent) { /* ctor bind */ + if (nv_mclass(parent->parent) == NV_DEVICE) { + /* delayed, or no, binding */ + return 0; + } + ret = impl->bind(dmaobj, parent, pgpuobj); + if (ret == 0) + nouveau_object_ref(NULL, &parent); + return ret; + } + + return impl->bind(dmaobj, parent, pgpuobj); +} + +int +nvkm_dmaobj_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) + struct nouveau_oclass *oclass, void **pdata, u32 *psize, + int length, void **pobject) { - struct nouveau_dmaeng *dmaeng = (void *)engine; + union { + struct nv_dma_v0 v0; + } *args = *pdata; + struct nouveau_instmem *instmem = nouveau_instmem(parent); + struct nouveau_client *client = nouveau_client(parent); + struct nouveau_device *device = nv_device(parent); + struct nouveau_fb *pfb = nouveau_fb(parent); struct nouveau_dmaobj *dmaobj; - struct nouveau_gpuobj *gpuobj; - struct nv_dma_class *args = data; + void *data = *pdata; + u32 size = *psize; int ret; - if (size < sizeof(*args)) - return -EINVAL; - - ret = nouveau_object_create(parent, engine, oclass, 0, &dmaobj); - *pobject = nv_object(dmaobj); + ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject); + dmaobj = *pobject; if (ret) return ret; - switch (args->flags & NV_DMA_TARGET_MASK) { - case NV_DMA_TARGET_VM: + nv_ioctl(parent, "create dma size %d\n", *psize); + if (nvif_unpack(args->v0, 0, 0, true)) { + nv_ioctl(parent, "create dma vers %d target %d access %d " + "start %016llx limit %016llx\n", + args->v0.version, args->v0.target, args->v0.access, + args->v0.start, args->v0.limit); + dmaobj->target = args->v0.target; + dmaobj->access = args->v0.access; + dmaobj->start = args->v0.start; + dmaobj->limit = args->v0.limit; + } else + return ret; + + *pdata = data; + *psize = size; + + if (dmaobj->start > dmaobj->limit) + return -EINVAL; + + switch (dmaobj->target) { + case NV_DMA_V0_TARGET_VM: dmaobj->target = NV_MEM_TARGET_VM; break; - case NV_DMA_TARGET_VRAM: + case NV_DMA_V0_TARGET_VRAM: + if (!client->super) { + if (dmaobj->limit >= pfb->ram->size - instmem->reserved) + return -EACCES; + if (device->card_type >= NV_50) + return -EACCES; + } dmaobj->target = NV_MEM_TARGET_VRAM; break; - case NV_DMA_TARGET_PCI: + case NV_DMA_V0_TARGET_PCI: + if (!client->super) + return -EACCES; dmaobj->target = NV_MEM_TARGET_PCI; break; - case NV_DMA_TARGET_PCI_US: - case NV_DMA_TARGET_AGP: + case NV_DMA_V0_TARGET_PCI_US: + case NV_DMA_V0_TARGET_AGP: + if (!client->super) + return -EACCES; dmaobj->target = NV_MEM_TARGET_PCI_NOSNOOP; break; default: return -EINVAL; } - switch (args->flags & NV_DMA_ACCESS_MASK) { - case NV_DMA_ACCESS_VM: + switch (dmaobj->access) { + case NV_DMA_V0_ACCESS_VM: dmaobj->access = NV_MEM_ACCESS_VM; break; - case NV_DMA_ACCESS_RD: + case NV_DMA_V0_ACCESS_RD: dmaobj->access = NV_MEM_ACCESS_RO; break; - case NV_DMA_ACCESS_WR: + case NV_DMA_V0_ACCESS_WR: dmaobj->access = NV_MEM_ACCESS_WO; break; - case NV_DMA_ACCESS_RDWR: + case NV_DMA_V0_ACCESS_RDWR: dmaobj->access = NV_MEM_ACCESS_RW; break; default: return -EINVAL; } - dmaobj->start = args->start; - dmaobj->limit = args->limit; - dmaobj->conf0 = args->conf0; - - switch (nv_mclass(parent)) { - case NV_DEVICE_CLASS: - /* delayed, or no, binding */ - break; - default: - ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj); - if (ret == 0) { - nouveau_object_ref(NULL, pobject); - *pobject = nv_object(gpuobj); - } - break; - } - return ret; } -static struct nouveau_ofuncs -nouveau_dmaobj_ofuncs = { - .ctor = nouveau_dmaobj_ctor, - .dtor = nouveau_object_destroy, - .init = nouveau_object_init, - .fini = nouveau_object_fini, -}; - -struct nouveau_oclass -nouveau_dmaobj_sclass[] = { - { NV_DMA_FROM_MEMORY_CLASS, &nouveau_dmaobj_ofuncs }, - { NV_DMA_TO_MEMORY_CLASS, &nouveau_dmaobj_ofuncs }, - { NV_DMA_IN_MEMORY_CLASS, &nouveau_dmaobj_ofuncs }, - {} -}; +int +_nvkm_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + const struct nvkm_dmaeng_impl *impl = (void *)oclass; + struct nouveau_dmaeng *dmaeng; + int ret; + + ret = nouveau_engine_create(parent, engine, oclass, true, "DMAOBJ", + "dmaobj", &dmaeng); + *pobject = nv_object(dmaeng); + if (ret) + return ret; + + nv_engine(dmaeng)->sclass = impl->sclass; + dmaeng->bind = nvkm_dmaobj_bind; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c index 027d8217c0fa..20c9dbfe3b2e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c @@ -23,121 +23,143 @@ */ #include <core/gpuobj.h> -#include <core/class.h> +#include <nvif/class.h> #include <subdev/fb.h> #include <subdev/vm/nv04.h> -#include <engine/dmaobj.h> +#include "priv.h" -struct nv04_dmaeng_priv { - struct nouveau_dmaeng base; +struct nv04_dmaobj_priv { + struct nouveau_dmaobj base; + bool clone; + u32 flags0; + u32 flags2; }; static int -nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng, +nv04_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent, - struct nouveau_dmaobj *dmaobj, struct nouveau_gpuobj **pgpuobj) { - struct nv04_vmmgr_priv *vmm = nv04_vmmgr(dmaeng); + struct nv04_dmaobj_priv *priv = (void *)dmaobj; struct nouveau_gpuobj *gpuobj; - u32 flags0 = nv_mclass(dmaobj); - u32 flags2 = 0x00000000; - u64 offset = dmaobj->start & 0xfffff000; - u64 adjust = dmaobj->start & 0x00000fff; - u32 length = dmaobj->limit - dmaobj->start; + u64 offset = priv->base.start & 0xfffff000; + u64 adjust = priv->base.start & 0x00000fff; + u32 length = priv->base.limit - priv->base.start; int ret; if (!nv_iclass(parent, NV_ENGCTX_CLASS)) { switch (nv_mclass(parent->parent)) { - case NV03_CHANNEL_DMA_CLASS: - case NV10_CHANNEL_DMA_CLASS: - case NV17_CHANNEL_DMA_CLASS: - case NV40_CHANNEL_DMA_CLASS: + case NV03_CHANNEL_DMA: + case NV10_CHANNEL_DMA: + case NV17_CHANNEL_DMA: + case NV40_CHANNEL_DMA: break; default: return -EINVAL; } } - if (dmaobj->target == NV_MEM_TARGET_VM) { - if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) { - struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0]; - if (!dmaobj->start) - return nouveau_gpuobj_dup(parent, pgt, pgpuobj); - offset = nv_ro32(pgt, 8 + (offset >> 10)); - offset &= 0xfffff000; - } + if (priv->clone) { + struct nv04_vmmgr_priv *vmm = nv04_vmmgr(dmaobj); + struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0]; + if (!dmaobj->start) + return nouveau_gpuobj_dup(parent, pgt, pgpuobj); + offset = nv_ro32(pgt, 8 + (offset >> 10)); + offset &= 0xfffff000; + } + + ret = nouveau_gpuobj_new(parent, parent, 16, 16, 0, &gpuobj); + *pgpuobj = gpuobj; + if (ret == 0) { + nv_wo32(*pgpuobj, 0x00, priv->flags0 | (adjust << 20)); + nv_wo32(*pgpuobj, 0x04, length); + nv_wo32(*pgpuobj, 0x08, priv->flags2 | offset); + nv_wo32(*pgpuobj, 0x0c, priv->flags2 | offset); + } + + return ret; +} + +static int +nv04_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_dmaeng *dmaeng = (void *)engine; + struct nv04_vmmgr_priv *vmm = nv04_vmmgr(engine); + struct nv04_dmaobj_priv *priv; + int ret; + + ret = nvkm_dmaobj_create(parent, engine, oclass, &data, &size, &priv); + *pobject = nv_object(priv); + if (ret || (ret = -ENOSYS, size)) + return ret; - dmaobj->target = NV_MEM_TARGET_PCI; - dmaobj->access = NV_MEM_ACCESS_RW; + if (priv->base.target == NV_MEM_TARGET_VM) { + if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) + priv->clone = true; + priv->base.target = NV_MEM_TARGET_PCI; + priv->base.access = NV_MEM_ACCESS_RW; } - switch (dmaobj->target) { + priv->flags0 = nv_mclass(priv); + switch (priv->base.target) { case NV_MEM_TARGET_VRAM: - flags0 |= 0x00003000; + priv->flags0 |= 0x00003000; break; case NV_MEM_TARGET_PCI: - flags0 |= 0x00023000; + priv->flags0 |= 0x00023000; break; case NV_MEM_TARGET_PCI_NOSNOOP: - flags0 |= 0x00033000; + priv->flags0 |= 0x00033000; break; default: return -EINVAL; } - switch (dmaobj->access) { + switch (priv->base.access) { case NV_MEM_ACCESS_RO: - flags0 |= 0x00004000; + priv->flags0 |= 0x00004000; break; case NV_MEM_ACCESS_WO: - flags0 |= 0x00008000; + priv->flags0 |= 0x00008000; case NV_MEM_ACCESS_RW: - flags2 |= 0x00000002; + priv->flags2 |= 0x00000002; break; default: return -EINVAL; } - ret = nouveau_gpuobj_new(parent, parent, 16, 16, 0, &gpuobj); - *pgpuobj = gpuobj; - if (ret == 0) { - nv_wo32(*pgpuobj, 0x00, flags0 | (adjust << 20)); - nv_wo32(*pgpuobj, 0x04, length); - nv_wo32(*pgpuobj, 0x08, flags2 | offset); - nv_wo32(*pgpuobj, 0x0c, flags2 | offset); - } - - return ret; + return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject); } -static int -nv04_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv04_dmaeng_priv *priv; - int ret; - - ret = nouveau_dmaeng_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; +static struct nouveau_ofuncs +nv04_dmaobj_ofuncs = { + .ctor = nv04_dmaobj_ctor, + .dtor = _nvkm_dmaobj_dtor, + .init = _nvkm_dmaobj_init, + .fini = _nvkm_dmaobj_fini, +}; - nv_engine(priv)->sclass = nouveau_dmaobj_sclass; - priv->base.bind = nv04_dmaobj_bind; - return 0; -} +static struct nouveau_oclass +nv04_dmaeng_sclass[] = { + { NV_DMA_FROM_MEMORY, &nv04_dmaobj_ofuncs }, + { NV_DMA_TO_MEMORY, &nv04_dmaobj_ofuncs }, + { NV_DMA_IN_MEMORY, &nv04_dmaobj_ofuncs }, + {} +}; -struct nouveau_oclass -nv04_dmaeng_oclass = { - .handle = NV_ENGINE(DMAOBJ, 0x04), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_dmaeng_ctor, - .dtor = _nouveau_dmaeng_dtor, - .init = _nouveau_dmaeng_init, - .fini = _nouveau_dmaeng_fini, +struct nouveau_oclass * +nv04_dmaeng_oclass = &(struct nvkm_dmaeng_impl) { + .base.handle = NV_ENGINE(DMAOBJ, 0x04), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_dmaeng_ctor, + .dtor = _nvkm_dmaeng_dtor, + .init = _nvkm_dmaeng_init, + .fini = _nvkm_dmaeng_fini, }, -}; + .sclass = nv04_dmaeng_sclass, + .bind = nv04_dmaobj_bind, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c index 750183f7c057..a740ddba2ee2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c @@ -22,140 +22,176 @@ * Authors: Ben Skeggs */ +#include <core/client.h> #include <core/gpuobj.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/fb.h> -#include <engine/dmaobj.h> -struct nv50_dmaeng_priv { - struct nouveau_dmaeng base; +#include "priv.h" + +struct nv50_dmaobj_priv { + struct nouveau_dmaobj base; + u32 flags0; + u32 flags5; }; static int -nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng, +nv50_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent, - struct nouveau_dmaobj *dmaobj, struct nouveau_gpuobj **pgpuobj) { - u32 flags0 = nv_mclass(dmaobj); - u32 flags5 = 0x00000000; + struct nv50_dmaobj_priv *priv = (void *)dmaobj; int ret; if (!nv_iclass(parent, NV_ENGCTX_CLASS)) { switch (nv_mclass(parent->parent)) { - case NV50_CHANNEL_DMA_CLASS: - case NV84_CHANNEL_DMA_CLASS: - case NV50_CHANNEL_IND_CLASS: - case NV84_CHANNEL_IND_CLASS: - case NV50_DISP_MAST_CLASS: - case NV84_DISP_MAST_CLASS: - case NV94_DISP_MAST_CLASS: - case NVA0_DISP_MAST_CLASS: - case NVA3_DISP_MAST_CLASS: - case NV50_DISP_SYNC_CLASS: - case NV84_DISP_SYNC_CLASS: - case NV94_DISP_SYNC_CLASS: - case NVA0_DISP_SYNC_CLASS: - case NVA3_DISP_SYNC_CLASS: - case NV50_DISP_OVLY_CLASS: - case NV84_DISP_OVLY_CLASS: - case NV94_DISP_OVLY_CLASS: - case NVA0_DISP_OVLY_CLASS: - case NVA3_DISP_OVLY_CLASS: + case NV40_CHANNEL_DMA: + case NV50_CHANNEL_GPFIFO: + case G82_CHANNEL_GPFIFO: + case NV50_DISP_CORE_CHANNEL_DMA: + case G82_DISP_CORE_CHANNEL_DMA: + case GT206_DISP_CORE_CHANNEL_DMA: + case GT200_DISP_CORE_CHANNEL_DMA: + case GT214_DISP_CORE_CHANNEL_DMA: + case NV50_DISP_BASE_CHANNEL_DMA: + case G82_DISP_BASE_CHANNEL_DMA: + case GT200_DISP_BASE_CHANNEL_DMA: + case GT214_DISP_BASE_CHANNEL_DMA: + case NV50_DISP_OVERLAY_CHANNEL_DMA: + case G82_DISP_OVERLAY_CHANNEL_DMA: + case GT200_DISP_OVERLAY_CHANNEL_DMA: + case GT214_DISP_OVERLAY_CHANNEL_DMA: break; default: return -EINVAL; } } - if (!(dmaobj->conf0 & NV50_DMA_CONF0_ENABLE)) { - if (dmaobj->target == NV_MEM_TARGET_VM) { - dmaobj->conf0 = NV50_DMA_CONF0_PRIV_VM; - dmaobj->conf0 |= NV50_DMA_CONF0_PART_VM; - dmaobj->conf0 |= NV50_DMA_CONF0_COMP_VM; - dmaobj->conf0 |= NV50_DMA_CONF0_TYPE_VM; + ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj); + if (ret == 0) { + nv_wo32(*pgpuobj, 0x00, priv->flags0 | nv_mclass(dmaobj)); + nv_wo32(*pgpuobj, 0x04, lower_32_bits(priv->base.limit)); + nv_wo32(*pgpuobj, 0x08, lower_32_bits(priv->base.start)); + nv_wo32(*pgpuobj, 0x0c, upper_32_bits(priv->base.limit) << 24 | + upper_32_bits(priv->base.start)); + nv_wo32(*pgpuobj, 0x10, 0x00000000); + nv_wo32(*pgpuobj, 0x14, priv->flags5); + } + + return ret; +} + +static int +nv50_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_dmaeng *dmaeng = (void *)engine; + union { + struct nv50_dma_v0 v0; + } *args; + struct nv50_dmaobj_priv *priv; + u32 user, part, comp, kind; + int ret; + + ret = nvkm_dmaobj_create(parent, engine, oclass, &data, &size, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + args = data; + + nv_ioctl(parent, "create nv50 dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create nv50 dma vers %d priv %d part %d " + "comp %d kind %02x\n", args->v0.version, + args->v0.priv, args->v0.part, args->v0.comp, + args->v0.kind); + user = args->v0.priv; + part = args->v0.part; + comp = args->v0.comp; + kind = args->v0.kind; + } else + if (size == 0) { + if (priv->base.target != NV_MEM_TARGET_VM) { + user = NV50_DMA_V0_PRIV_US; + part = NV50_DMA_V0_PART_256; + comp = NV50_DMA_V0_COMP_NONE; + kind = NV50_DMA_V0_KIND_PITCH; } else { - dmaobj->conf0 = NV50_DMA_CONF0_PRIV_US; - dmaobj->conf0 |= NV50_DMA_CONF0_PART_256; - dmaobj->conf0 |= NV50_DMA_CONF0_COMP_NONE; - dmaobj->conf0 |= NV50_DMA_CONF0_TYPE_LINEAR; + user = NV50_DMA_V0_PRIV_VM; + part = NV50_DMA_V0_PART_VM; + comp = NV50_DMA_V0_COMP_VM; + kind = NV50_DMA_V0_KIND_VM; } - } + } else + return ret; - flags0 |= (dmaobj->conf0 & NV50_DMA_CONF0_COMP) << 22; - flags0 |= (dmaobj->conf0 & NV50_DMA_CONF0_TYPE) << 22; - flags0 |= (dmaobj->conf0 & NV50_DMA_CONF0_PRIV); - flags5 |= (dmaobj->conf0 & NV50_DMA_CONF0_PART); + if (user > 2 || part > 2 || comp > 3 || kind > 0x7f) + return -EINVAL; + priv->flags0 = (comp << 29) | (kind << 22) | (user << 20); + priv->flags5 = (part << 16); - switch (dmaobj->target) { + switch (priv->base.target) { case NV_MEM_TARGET_VM: - flags0 |= 0x00000000; + priv->flags0 |= 0x00000000; break; case NV_MEM_TARGET_VRAM: - flags0 |= 0x00010000; + priv->flags0 |= 0x00010000; break; case NV_MEM_TARGET_PCI: - flags0 |= 0x00020000; + priv->flags0 |= 0x00020000; break; case NV_MEM_TARGET_PCI_NOSNOOP: - flags0 |= 0x00030000; + priv->flags0 |= 0x00030000; break; default: return -EINVAL; } - switch (dmaobj->access) { + switch (priv->base.access) { case NV_MEM_ACCESS_VM: break; case NV_MEM_ACCESS_RO: - flags0 |= 0x00040000; + priv->flags0 |= 0x00040000; break; case NV_MEM_ACCESS_WO: case NV_MEM_ACCESS_RW: - flags0 |= 0x00080000; + priv->flags0 |= 0x00080000; break; + default: + return -EINVAL; } - ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj); - if (ret == 0) { - nv_wo32(*pgpuobj, 0x00, flags0); - nv_wo32(*pgpuobj, 0x04, lower_32_bits(dmaobj->limit)); - nv_wo32(*pgpuobj, 0x08, lower_32_bits(dmaobj->start)); - nv_wo32(*pgpuobj, 0x0c, upper_32_bits(dmaobj->limit) << 24 | - upper_32_bits(dmaobj->start)); - nv_wo32(*pgpuobj, 0x10, 0x00000000); - nv_wo32(*pgpuobj, 0x14, flags5); - } - - return ret; + return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject); } -static int -nv50_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_dmaeng_priv *priv; - int ret; - - ret = nouveau_dmaeng_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; +static struct nouveau_ofuncs +nv50_dmaobj_ofuncs = { + .ctor = nv50_dmaobj_ctor, + .dtor = _nvkm_dmaobj_dtor, + .init = _nvkm_dmaobj_init, + .fini = _nvkm_dmaobj_fini, +}; - nv_engine(priv)->sclass = nouveau_dmaobj_sclass; - priv->base.bind = nv50_dmaobj_bind; - return 0; -} +static struct nouveau_oclass +nv50_dmaeng_sclass[] = { + { NV_DMA_FROM_MEMORY, &nv50_dmaobj_ofuncs }, + { NV_DMA_TO_MEMORY, &nv50_dmaobj_ofuncs }, + { NV_DMA_IN_MEMORY, &nv50_dmaobj_ofuncs }, + {} +}; -struct nouveau_oclass -nv50_dmaeng_oclass = { - .handle = NV_ENGINE(DMAOBJ, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_dmaeng_ctor, - .dtor = _nouveau_dmaeng_dtor, - .init = _nouveau_dmaeng_init, - .fini = _nouveau_dmaeng_fini, +struct nouveau_oclass * +nv50_dmaeng_oclass = &(struct nvkm_dmaeng_impl) { + .base.handle = NV_ENGINE(DMAOBJ, 0x50), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_dmaeng_ctor, + .dtor = _nvkm_dmaeng_dtor, + .init = _nvkm_dmaeng_init, + .fini = _nvkm_dmaeng_fini, }, -}; + .sclass = nv50_dmaeng_sclass, + .bind = nv50_dmaobj_bind, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c index cd3970d03b80..88ec33b20048 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvc0.c @@ -22,32 +22,35 @@ * Authors: Ben Skeggs */ +#include <core/client.h> #include <core/device.h> #include <core/gpuobj.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/fb.h> -#include <engine/dmaobj.h> -struct nvc0_dmaeng_priv { - struct nouveau_dmaeng base; +#include "priv.h" + +struct nvc0_dmaobj_priv { + struct nouveau_dmaobj base; + u32 flags0; + u32 flags5; }; static int -nvc0_dmaobj_bind(struct nouveau_dmaeng *dmaeng, +nvc0_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent, - struct nouveau_dmaobj *dmaobj, struct nouveau_gpuobj **pgpuobj) { - u32 flags0 = nv_mclass(dmaobj); - u32 flags5 = 0x00000000; + struct nvc0_dmaobj_priv *priv = (void *)dmaobj; int ret; if (!nv_iclass(parent, NV_ENGCTX_CLASS)) { switch (nv_mclass(parent->parent)) { - case NVA3_DISP_MAST_CLASS: - case NVA3_DISP_SYNC_CLASS: - case NVA3_DISP_OVLY_CLASS: + case GT214_DISP_CORE_CHANNEL_DMA: + case GT214_DISP_BASE_CHANNEL_DMA: + case GT214_DISP_OVERLAY_CHANNEL_DMA: break; default: return -EINVAL; @@ -55,89 +58,122 @@ nvc0_dmaobj_bind(struct nouveau_dmaeng *dmaeng, } else return 0; - if (!(dmaobj->conf0 & NVC0_DMA_CONF0_ENABLE)) { - if (dmaobj->target == NV_MEM_TARGET_VM) { - dmaobj->conf0 = NVC0_DMA_CONF0_PRIV_VM; - dmaobj->conf0 |= NVC0_DMA_CONF0_TYPE_VM; + ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj); + if (ret == 0) { + nv_wo32(*pgpuobj, 0x00, priv->flags0 | nv_mclass(dmaobj)); + nv_wo32(*pgpuobj, 0x04, lower_32_bits(priv->base.limit)); + nv_wo32(*pgpuobj, 0x08, lower_32_bits(priv->base.start)); + nv_wo32(*pgpuobj, 0x0c, upper_32_bits(priv->base.limit) << 24 | + upper_32_bits(priv->base.start)); + nv_wo32(*pgpuobj, 0x10, 0x00000000); + nv_wo32(*pgpuobj, 0x14, priv->flags5); + } + + return ret; +} + +static int +nvc0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_dmaeng *dmaeng = (void *)engine; + union { + struct gf100_dma_v0 v0; + } *args; + struct nvc0_dmaobj_priv *priv; + u32 kind, user, unkn; + int ret; + + ret = nvkm_dmaobj_create(parent, engine, oclass, &data, &size, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + args = data; + + nv_ioctl(parent, "create gf100 dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create gf100 dma vers %d priv %d kind %02x\n", + args->v0.version, args->v0.priv, args->v0.kind); + kind = args->v0.kind; + user = args->v0.priv; + unkn = 0; + } else + if (size == 0) { + if (priv->base.target != NV_MEM_TARGET_VM) { + kind = GF100_DMA_V0_KIND_PITCH; + user = GF100_DMA_V0_PRIV_US; + unkn = 2; } else { - dmaobj->conf0 = NVC0_DMA_CONF0_PRIV_US; - dmaobj->conf0 |= NVC0_DMA_CONF0_TYPE_LINEAR; - dmaobj->conf0 |= 0x00020000; + kind = GF100_DMA_V0_KIND_VM; + user = GF100_DMA_V0_PRIV_VM; + unkn = 0; } - } + } else + return ret; - flags0 |= (dmaobj->conf0 & NVC0_DMA_CONF0_TYPE) << 22; - flags0 |= (dmaobj->conf0 & NVC0_DMA_CONF0_PRIV); - flags5 |= (dmaobj->conf0 & NVC0_DMA_CONF0_UNKN); + if (user > 2) + return -EINVAL; + priv->flags0 |= (kind << 22) | (user << 20); + priv->flags5 |= (unkn << 16); - switch (dmaobj->target) { + switch (priv->base.target) { case NV_MEM_TARGET_VM: - flags0 |= 0x00000000; + priv->flags0 |= 0x00000000; break; case NV_MEM_TARGET_VRAM: - flags0 |= 0x00010000; + priv->flags0 |= 0x00010000; break; case NV_MEM_TARGET_PCI: - flags0 |= 0x00020000; + priv->flags0 |= 0x00020000; break; case NV_MEM_TARGET_PCI_NOSNOOP: - flags0 |= 0x00030000; + priv->flags0 |= 0x00030000; break; default: return -EINVAL; } - switch (dmaobj->access) { + switch (priv->base.access) { case NV_MEM_ACCESS_VM: break; case NV_MEM_ACCESS_RO: - flags0 |= 0x00040000; + priv->flags0 |= 0x00040000; break; case NV_MEM_ACCESS_WO: case NV_MEM_ACCESS_RW: - flags0 |= 0x00080000; + priv->flags0 |= 0x00080000; break; } - ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj); - if (ret == 0) { - nv_wo32(*pgpuobj, 0x00, flags0); - nv_wo32(*pgpuobj, 0x04, lower_32_bits(dmaobj->limit)); - nv_wo32(*pgpuobj, 0x08, lower_32_bits(dmaobj->start)); - nv_wo32(*pgpuobj, 0x0c, upper_32_bits(dmaobj->limit) << 24 | - upper_32_bits(dmaobj->start)); - nv_wo32(*pgpuobj, 0x10, 0x00000000); - nv_wo32(*pgpuobj, 0x14, flags5); - } - - return ret; + return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject); } -static int -nvc0_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvc0_dmaeng_priv *priv; - int ret; - - ret = nouveau_dmaeng_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; +static struct nouveau_ofuncs +nvc0_dmaobj_ofuncs = { + .ctor = nvc0_dmaobj_ctor, + .dtor = _nvkm_dmaobj_dtor, + .init = _nvkm_dmaobj_init, + .fini = _nvkm_dmaobj_fini, +}; - nv_engine(priv)->sclass = nouveau_dmaobj_sclass; - priv->base.bind = nvc0_dmaobj_bind; - return 0; -} +static struct nouveau_oclass +nvc0_dmaeng_sclass[] = { + { NV_DMA_FROM_MEMORY, &nvc0_dmaobj_ofuncs }, + { NV_DMA_TO_MEMORY, &nvc0_dmaobj_ofuncs }, + { NV_DMA_IN_MEMORY, &nvc0_dmaobj_ofuncs }, + {} +}; -struct nouveau_oclass -nvc0_dmaeng_oclass = { - .handle = NV_ENGINE(DMAOBJ, 0xc0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_dmaeng_ctor, - .dtor = _nouveau_dmaeng_dtor, - .init = _nouveau_dmaeng_init, - .fini = _nouveau_dmaeng_fini, +struct nouveau_oclass * +nvc0_dmaeng_oclass = &(struct nvkm_dmaeng_impl) { + .base.handle = NV_ENGINE(DMAOBJ, 0xc0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_dmaeng_ctor, + .dtor = _nvkm_dmaeng_dtor, + .init = _nvkm_dmaeng_init, + .fini = _nvkm_dmaeng_fini, }, -}; + .sclass = nvc0_dmaeng_sclass, + .bind = nvc0_dmaobj_bind, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c index 1cfb3bb90131..3fc4f0b0eaca 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c @@ -22,40 +22,40 @@ * Authors: Ben Skeggs */ +#include <core/client.h> #include <core/device.h> #include <core/gpuobj.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/fb.h> -#include <engine/dmaobj.h> -struct nvd0_dmaeng_priv { - struct nouveau_dmaeng base; +#include "priv.h" + +struct nvd0_dmaobj_priv { + struct nouveau_dmaobj base; + u32 flags0; }; static int -nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng, +nvd0_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent, - struct nouveau_dmaobj *dmaobj, struct nouveau_gpuobj **pgpuobj) { - u32 flags0 = 0x00000000; + struct nvd0_dmaobj_priv *priv = (void *)dmaobj; int ret; if (!nv_iclass(parent, NV_ENGCTX_CLASS)) { switch (nv_mclass(parent->parent)) { - case NVD0_DISP_MAST_CLASS: - case NVD0_DISP_SYNC_CLASS: - case NVD0_DISP_OVLY_CLASS: - case NVE0_DISP_MAST_CLASS: - case NVE0_DISP_SYNC_CLASS: - case NVE0_DISP_OVLY_CLASS: - case NVF0_DISP_MAST_CLASS: - case NVF0_DISP_SYNC_CLASS: - case NVF0_DISP_OVLY_CLASS: - case GM107_DISP_MAST_CLASS: - case GM107_DISP_SYNC_CLASS: - case GM107_DISP_OVLY_CLASS: + case GF110_DISP_CORE_CHANNEL_DMA: + case GK104_DISP_CORE_CHANNEL_DMA: + case GK110_DISP_CORE_CHANNEL_DMA: + case GM107_DISP_CORE_CHANNEL_DMA: + case GF110_DISP_BASE_CHANNEL_DMA: + case GK104_DISP_BASE_CHANNEL_DMA: + case GK110_DISP_BASE_CHANNEL_DMA: + case GF110_DISP_OVERLAY_CONTROL_DMA: + case GK104_DISP_OVERLAY_CONTROL_DMA: break; default: return -EINVAL; @@ -63,33 +63,11 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng, } else return 0; - if (!(dmaobj->conf0 & NVD0_DMA_CONF0_ENABLE)) { - if (dmaobj->target == NV_MEM_TARGET_VM) { - dmaobj->conf0 |= NVD0_DMA_CONF0_TYPE_VM; - dmaobj->conf0 |= NVD0_DMA_CONF0_PAGE_LP; - } else { - dmaobj->conf0 |= NVD0_DMA_CONF0_TYPE_LINEAR; - dmaobj->conf0 |= NVD0_DMA_CONF0_PAGE_SP; - } - } - - flags0 |= (dmaobj->conf0 & NVD0_DMA_CONF0_TYPE) << 20; - flags0 |= (dmaobj->conf0 & NVD0_DMA_CONF0_PAGE) >> 4; - - switch (dmaobj->target) { - case NV_MEM_TARGET_VRAM: - flags0 |= 0x00000009; - break; - default: - return -EINVAL; - break; - } - ret = nouveau_gpuobj_new(parent, parent, 24, 32, 0, pgpuobj); if (ret == 0) { - nv_wo32(*pgpuobj, 0x00, flags0); - nv_wo32(*pgpuobj, 0x04, dmaobj->start >> 8); - nv_wo32(*pgpuobj, 0x08, dmaobj->limit >> 8); + nv_wo32(*pgpuobj, 0x00, priv->flags0); + nv_wo32(*pgpuobj, 0x04, priv->base.start >> 8); + nv_wo32(*pgpuobj, 0x08, priv->base.limit >> 8); nv_wo32(*pgpuobj, 0x0c, 0x00000000); nv_wo32(*pgpuobj, 0x10, 0x00000000); nv_wo32(*pgpuobj, 0x14, 0x00000000); @@ -99,30 +77,91 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng, } static int -nvd0_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine, +nvd0_dmaobj_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nvd0_dmaeng_priv *priv; + struct nouveau_dmaeng *dmaeng = (void *)engine; + union { + struct gf110_dma_v0 v0; + } *args; + struct nvd0_dmaobj_priv *priv; + u32 kind, page; int ret; - ret = nouveau_dmaeng_create(parent, engine, oclass, &priv); + ret = nvkm_dmaobj_create(parent, engine, oclass, &data, &size, &priv); *pobject = nv_object(priv); if (ret) return ret; + args = data; - nv_engine(priv)->sclass = nouveau_dmaobj_sclass; - priv->base.bind = nvd0_dmaobj_bind; - return 0; + nv_ioctl(parent, "create gf110 dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create gf100 dma vers %d page %d kind %02x\n", + args->v0.version, args->v0.page, args->v0.kind); + kind = args->v0.kind; + page = args->v0.page; + } else + if (size == 0) { + if (priv->base.target != NV_MEM_TARGET_VM) { + kind = GF110_DMA_V0_KIND_PITCH; + page = GF110_DMA_V0_PAGE_SP; + } else { + kind = GF110_DMA_V0_KIND_VM; + page = GF110_DMA_V0_PAGE_LP; + } + } else + return ret; + + if (page > 1) + return -EINVAL; + priv->flags0 = (kind << 20) | (page << 6); + + switch (priv->base.target) { + case NV_MEM_TARGET_VRAM: + priv->flags0 |= 0x00000009; + break; + case NV_MEM_TARGET_VM: + case NV_MEM_TARGET_PCI: + case NV_MEM_TARGET_PCI_NOSNOOP: + /* XXX: don't currently know how to construct a real one + * of these. we only use them to represent pushbufs + * on these chipsets, and the classes that use them + * deal with the target themselves. + */ + break; + default: + return -EINVAL; + } + + return dmaeng->bind(&priv->base, nv_object(priv), (void *)pobject); } -struct nouveau_oclass -nvd0_dmaeng_oclass = { - .handle = NV_ENGINE(DMAOBJ, 0xd0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_dmaeng_ctor, - .dtor = _nouveau_dmaeng_dtor, - .init = _nouveau_dmaeng_init, - .fini = _nouveau_dmaeng_fini, - }, +static struct nouveau_ofuncs +nvd0_dmaobj_ofuncs = { + .ctor = nvd0_dmaobj_ctor, + .dtor = _nvkm_dmaobj_dtor, + .init = _nvkm_dmaobj_init, + .fini = _nvkm_dmaobj_fini, }; + +static struct nouveau_oclass +nvd0_dmaeng_sclass[] = { + { NV_DMA_FROM_MEMORY, &nvd0_dmaobj_ofuncs }, + { NV_DMA_TO_MEMORY, &nvd0_dmaobj_ofuncs }, + { NV_DMA_IN_MEMORY, &nvd0_dmaobj_ofuncs }, + {} +}; + +struct nouveau_oclass * +nvd0_dmaeng_oclass = &(struct nvkm_dmaeng_impl) { + .base.handle = NV_ENGINE(DMAOBJ, 0xd0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_dmaeng_ctor, + .dtor = _nvkm_dmaeng_dtor, + .init = _nvkm_dmaeng_init, + .fini = _nvkm_dmaeng_fini, + }, + .sclass = nvd0_dmaeng_sclass, + .bind = nvd0_dmaobj_bind, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h b/drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h new file mode 100644 index 000000000000..36f743866937 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/priv.h @@ -0,0 +1,30 @@ +#ifndef __NVKM_DMAOBJ_PRIV_H__ +#define __NVKM_DMAOBJ_PRIV_H__ + +#include <engine/dmaobj.h> + +#define nvkm_dmaobj_create(p,e,c,pa,sa,d) \ + nvkm_dmaobj_create_((p), (e), (c), (pa), (sa), sizeof(**d), (void **)d) + +int nvkm_dmaobj_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void **, u32 *, + int, void **); +#define _nvkm_dmaobj_dtor nouveau_object_destroy +#define _nvkm_dmaobj_init nouveau_object_init +#define _nvkm_dmaobj_fini nouveau_object_fini + +int _nvkm_dmaeng_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +#define _nvkm_dmaeng_dtor _nouveau_engine_dtor +#define _nvkm_dmaeng_init _nouveau_engine_init +#define _nvkm_dmaeng_fini _nouveau_engine_fini + +struct nvkm_dmaeng_impl { + struct nouveau_oclass base; + struct nouveau_oclass *sclass; + int (*bind)(struct nouveau_dmaobj *, struct nouveau_object *, + struct nouveau_gpuobj **); +}; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index 56ed3d73bf8e..0f999fc45ab9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -26,11 +26,30 @@ #include <core/object.h> #include <core/handle.h> #include <core/event.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> +#include <nvif/event.h> #include <engine/dmaobj.h> #include <engine/fifo.h> +static int +nouveau_fifo_event_ctor(void *data, u32 size, struct nvkm_notify *notify) +{ + if (size == 0) { + notify->size = 0; + notify->types = 1; + notify->index = 0; + return 0; + } + return -ENOSYS; +} + +static const struct nvkm_event_func +nouveau_fifo_event_func = { + .ctor = nouveau_fifo_event_ctor, +}; + int nouveau_fifo_channel_create_(struct nouveau_object *parent, struct nouveau_object *engine, @@ -59,14 +78,14 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, dmaeng = (void *)chan->pushdma->base.engine; switch (chan->pushdma->base.oclass->handle) { - case NV_DMA_FROM_MEMORY_CLASS: - case NV_DMA_IN_MEMORY_CLASS: + case NV_DMA_FROM_MEMORY: + case NV_DMA_IN_MEMORY: break; default: return -EINVAL; } - ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu); + ret = dmaeng->bind(chan->pushdma, parent, &chan->pushgpu); if (ret) return ret; @@ -85,15 +104,10 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, return -ENOSPC; } - /* map fifo control registers */ - chan->user = ioremap(nv_device_resource_start(device, bar) + addr + - (chan->chid * size), size); - if (!chan->user) - return -EFAULT; - - nouveau_event_trigger(priv->cevent, 1, 0); - + chan->addr = nv_device_resource_start(device, bar) + + addr + size * chan->chid; chan->size = size; + nvkm_event_send(&priv->cevent, 1, 0, NULL, 0); return 0; } @@ -103,7 +117,8 @@ nouveau_fifo_channel_destroy(struct nouveau_fifo_chan *chan) struct nouveau_fifo *priv = (void *)nv_object(chan)->engine; unsigned long flags; - iounmap(chan->user); + if (chan->user) + iounmap(chan->user); spin_lock_irqsave(&priv->lock, flags); priv->channel[chan->chid] = NULL; @@ -121,10 +136,24 @@ _nouveau_fifo_channel_dtor(struct nouveau_object *object) nouveau_fifo_channel_destroy(chan); } +int +_nouveau_fifo_channel_map(struct nouveau_object *object, u64 *addr, u32 *size) +{ + struct nouveau_fifo_chan *chan = (void *)object; + *addr = chan->addr; + *size = chan->size; + return 0; +} + u32 _nouveau_fifo_channel_rd32(struct nouveau_object *object, u64 addr) { struct nouveau_fifo_chan *chan = (void *)object; + if (unlikely(!chan->user)) { + chan->user = ioremap(chan->addr, chan->size); + if (WARN_ON_ONCE(chan->user == NULL)) + return 0; + } return ioread32_native(chan->user + addr); } @@ -132,9 +161,57 @@ void _nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data) { struct nouveau_fifo_chan *chan = (void *)object; + if (unlikely(!chan->user)) { + chan->user = ioremap(chan->addr, chan->size); + if (WARN_ON_ONCE(chan->user == NULL)) + return; + } iowrite32_native(data, chan->user + addr); } +int +nouveau_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify) +{ + union { + struct nvif_notify_uevent_req none; + } *req = data; + int ret; + + if (nvif_unvers(req->none)) { + notify->size = sizeof(struct nvif_notify_uevent_rep); + notify->types = 1; + notify->index = 0; + } + + return ret; +} + +void +nouveau_fifo_uevent(struct nouveau_fifo *fifo) +{ + struct nvif_notify_uevent_rep rep = { + }; + nvkm_event_send(&fifo->uevent, 1, 0, &rep, sizeof(rep)); +} + +int +_nouveau_fifo_channel_ntfy(struct nouveau_object *object, u32 type, + struct nvkm_event **event) +{ + struct nouveau_fifo *fifo = (void *)object->engine; + switch (type) { + case G82_CHANNEL_DMA_V0_NTFY_UEVENT: + if (nv_mclass(object) >= G82_CHANNEL_DMA) { + *event = &fifo->uevent; + return 0; + } + break; + default: + break; + } + return -EINVAL; +} + static int nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object) { @@ -168,8 +245,8 @@ void nouveau_fifo_destroy(struct nouveau_fifo *priv) { kfree(priv->channel); - nouveau_event_destroy(&priv->uevent); - nouveau_event_destroy(&priv->cevent); + nvkm_event_fini(&priv->uevent); + nvkm_event_fini(&priv->cevent); nouveau_engine_destroy(&priv->base); } @@ -194,11 +271,7 @@ nouveau_fifo_create_(struct nouveau_object *parent, if (!priv->channel) return -ENOMEM; - ret = nouveau_event_create(1, 1, &priv->cevent); - if (ret) - return ret; - - ret = nouveau_event_create(1, 1, &priv->uevent); + ret = nvkm_event_init(&nouveau_fifo_event_func, 1, 1, &priv->cevent); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index c61b16a63884..5ae6a43893b5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/engctx.h> #include <core/namedb.h> #include <core/handle.h> @@ -117,16 +118,23 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv03_channel_dma_v0 v0; + } *args = data; struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; - struct nv03_channel_dma_class *args = data; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " + "offset %016llx\n", args->v0.version, + args->v0.pushbuf, args->v0.offset); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000, - 0x10000, args->pushbuf, + 0x10000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR), &chan); @@ -134,13 +142,15 @@ nv04_fifo_chan_ctor(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->object_attach = nv04_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; nv_parent(chan)->context_attach = nv04_fifo_context_attach; chan->ramfc = chan->base.chid * 32; - nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset); - nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x08, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x10, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | @@ -242,13 +252,15 @@ nv04_fifo_ofuncs = { .dtor = nv04_fifo_chan_dtor, .init = nv04_fifo_chan_init, .fini = nv04_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nv04_fifo_sclass[] = { - { NV03_CHANNEL_DMA_CLASS, &nv04_fifo_ofuncs }, + { NV03_CHANNEL_DMA, &nv04_fifo_ofuncs }, {} }; @@ -539,7 +551,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) } if (status & 0x40000000) { - nouveau_event_trigger(priv->base.uevent, 1, 0); + nouveau_fifo_uevent(&priv->base); nv_wr32(priv, 0x002100, 0x40000000); status &= ~0x40000000; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c index 571a22aa1ae5..2a32add51c81 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/engctx.h> #include <core/ramht.h> @@ -59,16 +60,23 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv03_channel_dma_v0 v0; + } *args = data; struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; - struct nv03_channel_dma_class *args = data; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " + "offset %016llx\n", args->v0.version, + args->v0.pushbuf, args->v0.offset); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000, - 0x10000, args->pushbuf, + 0x10000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR), &chan); @@ -76,13 +84,15 @@ nv10_fifo_chan_ctor(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->object_attach = nv04_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; nv_parent(chan)->context_attach = nv04_fifo_context_attach; chan->ramfc = chan->base.chid * 32; - nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset); - nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | @@ -100,13 +110,15 @@ nv10_fifo_ofuncs = { .dtor = nv04_fifo_chan_dtor, .init = nv04_fifo_chan_init, .fini = nv04_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nv10_fifo_sclass[] = { - { NV10_CHANNEL_DMA_CLASS, &nv10_fifo_ofuncs }, + { NV10_CHANNEL_DMA, &nv10_fifo_ofuncs }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c index f25760209316..12d76c8adb23 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/engctx.h> #include <core/ramht.h> @@ -64,16 +65,23 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv03_channel_dma_v0 v0; + } *args = data; struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; - struct nv03_channel_dma_class *args = data; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " + "offset %016llx\n", args->v0.version, + args->v0.pushbuf, args->v0.offset); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0x800000, - 0x10000, args->pushbuf, + 0x10000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | @@ -83,13 +91,15 @@ nv17_fifo_chan_ctor(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->object_attach = nv04_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; nv_parent(chan)->context_attach = nv04_fifo_context_attach; chan->ramfc = chan->base.chid * 64; - nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset); - nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | @@ -107,13 +117,15 @@ nv17_fifo_ofuncs = { .dtor = nv04_fifo_chan_dtor, .init = nv04_fifo_chan_init, .fini = nv04_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nv17_fifo_sclass[] = { - { NV17_CHANNEL_DMA_CLASS, &nv17_fifo_ofuncs }, + { NV17_CHANNEL_DMA, &nv17_fifo_ofuncs }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c index 343487ed2238..9f49c3a24dc6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c @@ -22,8 +22,9 @@ * Authors: Ben Skeggs */ -#include <core/os.h> -#include <core/class.h> +#include <core/client.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/engctx.h> #include <core/ramht.h> @@ -182,16 +183,23 @@ nv40_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv03_channel_dma_v0 v0; + } *args = data; struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; - struct nv03_channel_dma_class *args = data; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " + "offset %016llx\n", args->v0.version, + args->v0.pushbuf, args->v0.offset); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000, - 0x1000, args->pushbuf, + 0x1000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | @@ -200,14 +208,16 @@ nv40_fifo_chan_ctor(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->context_attach = nv40_fifo_context_attach; nv_parent(chan)->context_detach = nv40_fifo_context_detach; nv_parent(chan)->object_attach = nv40_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; chan->ramfc = chan->base.chid * 128; - nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->offset); - nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset); + nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x18, 0x30000000 | NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | @@ -226,13 +236,15 @@ nv40_fifo_ofuncs = { .dtor = nv04_fifo_chan_dtor, .init = nv04_fifo_chan_init, .fini = nv04_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nv40_fifo_sclass[] = { - { NV40_CHANNEL_DMA_CLASS, &nv40_fifo_ofuncs }, + { NV40_CHANNEL_DMA, &nv40_fifo_ofuncs }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index e6352bd5b4ff..5d1e86bc244c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -25,7 +25,8 @@ #include <core/client.h> #include <core/engctx.h> #include <core/ramht.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/timer.h> #include <subdev/bar.h> @@ -194,17 +195,24 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv03_channel_dma_v0 v0; + } *args = data; struct nouveau_bar *bar = nouveau_bar(parent); struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; - struct nv03_channel_dma_class *args = data; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " + "offset %016llx\n", args->v0.version, + args->v0.pushbuf, args->v0.offset); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000, - 0x2000, args->pushbuf, + 0x2000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | @@ -213,6 +221,8 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->context_attach = nv50_fifo_context_attach; nv_parent(chan)->context_detach = nv50_fifo_context_detach; nv_parent(chan)->object_attach = nv50_fifo_object_attach; @@ -223,10 +233,10 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent, if (ret) return ret; - nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset)); - nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset)); - nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset)); - nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset)); + nv_wo32(base->ramfc, 0x08, lower_32_bits(args->v0.offset)); + nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->v0.offset)); + nv_wo32(base->ramfc, 0x10, lower_32_bits(args->v0.offset)); + nv_wo32(base->ramfc, 0x14, upper_32_bits(args->v0.offset)); nv_wo32(base->ramfc, 0x3c, 0x003f6078); nv_wo32(base->ramfc, 0x44, 0x01003fff); nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4); @@ -247,18 +257,26 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_channel_ind_class *args = data; + union { + struct nv50_channel_gpfifo_v0 v0; + } *args = data; struct nouveau_bar *bar = nouveau_bar(parent); struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; u64 ioffset, ilength; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel gpfifo size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " + "ioffset %016llx ilength %08x\n", + args->v0.version, args->v0.pushbuf, args->v0.ioffset, + args->v0.ilength); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000, - 0x2000, args->pushbuf, + 0x2000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | @@ -267,6 +285,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->context_attach = nv50_fifo_context_attach; nv_parent(chan)->context_detach = nv50_fifo_context_detach; nv_parent(chan)->object_attach = nv50_fifo_object_attach; @@ -277,8 +297,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent, if (ret) return ret; - ioffset = args->ioffset; - ilength = order_base_2(args->ilength / 8); + ioffset = args->v0.ioffset; + ilength = order_base_2(args->v0.ilength / 8); nv_wo32(base->ramfc, 0x3c, 0x403f6078); nv_wo32(base->ramfc, 0x44, 0x01003fff); @@ -343,8 +363,10 @@ nv50_fifo_ofuncs_dma = { .dtor = nv50_fifo_chan_dtor, .init = nv50_fifo_chan_init, .fini = nv50_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_ofuncs @@ -353,14 +375,16 @@ nv50_fifo_ofuncs_ind = { .dtor = nv50_fifo_chan_dtor, .init = nv50_fifo_chan_init, .fini = nv50_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nv50_fifo_sclass[] = { - { NV50_CHANNEL_DMA_CLASS, &nv50_fifo_ofuncs_dma }, - { NV50_CHANNEL_IND_CLASS, &nv50_fifo_ofuncs_ind }, + { NV50_CHANNEL_DMA, &nv50_fifo_ofuncs_dma }, + { NV50_CHANNEL_GPFIFO, &nv50_fifo_ofuncs_ind }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index 6e5ac16e5460..1f42996b354a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -27,7 +27,8 @@ #include <core/engctx.h> #include <core/ramht.h> #include <core/event.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <subdev/timer.h> #include <subdev/bar.h> @@ -160,17 +161,24 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv03_channel_dma_v0 v0; + } *args = data; struct nouveau_bar *bar = nouveau_bar(parent); struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; - struct nv03_channel_dma_class *args = data; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel dma size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " + "offset %016llx\n", args->v0.version, + args->v0.pushbuf, args->v0.offset); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000, - 0x2000, args->pushbuf, + 0x2000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | @@ -186,6 +194,8 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16, &chan->ramht); if (ret) @@ -196,10 +206,10 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent, nv_parent(chan)->object_attach = nv84_fifo_object_attach; nv_parent(chan)->object_detach = nv50_fifo_object_detach; - nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset)); - nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset)); - nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset)); - nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset)); + nv_wo32(base->ramfc, 0x08, lower_32_bits(args->v0.offset)); + nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->v0.offset)); + nv_wo32(base->ramfc, 0x10, lower_32_bits(args->v0.offset)); + nv_wo32(base->ramfc, 0x14, upper_32_bits(args->v0.offset)); nv_wo32(base->ramfc, 0x3c, 0x003f6078); nv_wo32(base->ramfc, 0x44, 0x01003fff); nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4); @@ -222,18 +232,26 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv50_channel_gpfifo_v0 v0; + } *args = data; struct nouveau_bar *bar = nouveau_bar(parent); struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_chan *chan; - struct nv50_channel_ind_class *args = data; u64 ioffset, ilength; int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel gpfifo size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " + "ioffset %016llx ilength %08x\n", + args->v0.version, args->v0.pushbuf, args->v0.ioffset, + args->v0.ilength); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000, - 0x2000, args->pushbuf, + 0x2000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | @@ -249,6 +267,8 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16, &chan->ramht); if (ret) @@ -259,8 +279,8 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent, nv_parent(chan)->object_attach = nv84_fifo_object_attach; nv_parent(chan)->object_detach = nv50_fifo_object_detach; - ioffset = args->ioffset; - ilength = order_base_2(args->ilength / 8); + ioffset = args->v0.ioffset; + ilength = order_base_2(args->v0.ilength / 8); nv_wo32(base->ramfc, 0x3c, 0x403f6078); nv_wo32(base->ramfc, 0x44, 0x01003fff); @@ -304,8 +324,10 @@ nv84_fifo_ofuncs_dma = { .dtor = nv50_fifo_chan_dtor, .init = nv84_fifo_chan_init, .fini = nv50_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_ofuncs @@ -314,14 +336,16 @@ nv84_fifo_ofuncs_ind = { .dtor = nv50_fifo_chan_dtor, .init = nv84_fifo_chan_init, .fini = nv50_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nv84_fifo_sclass[] = { - { NV84_CHANNEL_DMA_CLASS, &nv84_fifo_ofuncs_dma }, - { NV84_CHANNEL_IND_CLASS, &nv84_fifo_ofuncs_ind }, + { G82_CHANNEL_DMA, &nv84_fifo_ofuncs_dma }, + { G82_CHANNEL_GPFIFO, &nv84_fifo_ofuncs_ind }, {} }; @@ -389,19 +413,26 @@ nv84_fifo_cclass = { ******************************************************************************/ static void -nv84_fifo_uevent_enable(struct nouveau_event *event, int type, int index) +nv84_fifo_uevent_init(struct nvkm_event *event, int type, int index) { - struct nv84_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x40000000, 0x40000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x40000000, 0x40000000); } static void -nv84_fifo_uevent_disable(struct nouveau_event *event, int type, int index) +nv84_fifo_uevent_fini(struct nvkm_event *event, int type, int index) { - struct nv84_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x40000000, 0x00000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x40000000, 0x00000000); } +static const struct nvkm_event_func +nv84_fifo_uevent_func = { + .ctor = nouveau_fifo_uevent_ctor, + .init = nv84_fifo_uevent_init, + .fini = nv84_fifo_uevent_fini, +}; + static int nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -425,9 +456,9 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nv84_fifo_uevent_enable; - priv->base.uevent->disable = nv84_fifo_uevent_disable; - priv->base.uevent->priv = priv; + ret = nvkm_event_init(&nv84_fifo_uevent_func, 1, 1, &priv->base.uevent); + if (ret) + return ret; nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nv04_fifo_intr; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index ae4a4dc5642a..1fe1f8fbda0c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -28,7 +28,8 @@ #include <core/gpuobj.h> #include <core/engctx.h> #include <core/event.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/enum.h> #include <subdev/timer.h> @@ -187,20 +188,28 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nv50_channel_gpfifo_v0 v0; + } *args = data; struct nouveau_bar *bar = nouveau_bar(parent); struct nvc0_fifo_priv *priv = (void *)engine; struct nvc0_fifo_base *base = (void *)parent; struct nvc0_fifo_chan *chan; - struct nv50_channel_ind_class *args = data; u64 usermem, ioffset, ilength; int ret, i; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel gpfifo size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " + "ioffset %016llx ilength %08x\n", + args->v0.version, args->v0.pushbuf, args->v0.ioffset, + args->v0.ilength); + } else + return ret; ret = nouveau_fifo_channel_create(parent, engine, oclass, 1, priv->user.bar.offset, 0x1000, - args->pushbuf, + args->v0.pushbuf, (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR) | (1ULL << NVDEV_ENGINE_COPY0) | @@ -212,12 +221,14 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent, if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->context_attach = nvc0_fifo_context_attach; nv_parent(chan)->context_detach = nvc0_fifo_context_detach; usermem = chan->base.chid * 0x1000; - ioffset = args->ioffset; - ilength = order_base_2(args->ilength / 8); + ioffset = args->v0.ioffset; + ilength = order_base_2(args->v0.ilength / 8); for (i = 0; i < 0x1000; i += 4) nv_wo32(priv->user.mem, usermem + i, 0x00000000); @@ -291,13 +302,15 @@ nvc0_fifo_ofuncs = { .dtor = _nouveau_fifo_channel_dtor, .init = nvc0_fifo_chan_init, .fini = nvc0_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nvc0_fifo_sclass[] = { - { NVC0_CHANNEL_IND_CLASS, &nvc0_fifo_ofuncs }, + { FERMI_CHANNEL_GPFIFO, &nvc0_fifo_ofuncs }, {} }; @@ -654,7 +667,7 @@ nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit) object = engctx; while (object) { switch (nv_mclass(object)) { - case NVC0_CHANNEL_IND_CLASS: + case FERMI_CHANNEL_GPFIFO: nvc0_fifo_recover(priv, engine, (void *)object); break; } @@ -730,7 +743,7 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) for (unkn = 0; unkn < 8; unkn++) { u32 ints = (intr >> (unkn * 0x04)) & inte; if (ints & 0x1) { - nouveau_event_trigger(priv->base.uevent, 1, 0); + nouveau_fifo_uevent(&priv->base); ints &= ~1; } if (ints) { @@ -827,19 +840,26 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } static void -nvc0_fifo_uevent_enable(struct nouveau_event *event, int type, int index) +nvc0_fifo_uevent_init(struct nvkm_event *event, int type, int index) { - struct nvc0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x80000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x80000000, 0x80000000); } static void -nvc0_fifo_uevent_disable(struct nouveau_event *event, int type, int index) +nvc0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) { - struct nvc0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x00000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); } +static const struct nvkm_event_func +nvc0_fifo_uevent_func = { + .ctor = nouveau_fifo_uevent_ctor, + .init = nvc0_fifo_uevent_init, + .fini = nvc0_fifo_uevent_fini, +}; + static int nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -877,9 +897,9 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nvc0_fifo_uevent_enable; - priv->base.uevent->disable = nvc0_fifo_uevent_disable; - priv->base.uevent->priv = priv; + ret = nvkm_event_init(&nvc0_fifo_uevent_func, 1, 1, &priv->base.uevent); + if (ret) + return ret; nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nvc0_fifo_intr; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 298063edb92d..d2f0fd39c145 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -28,7 +28,8 @@ #include <core/gpuobj.h> #include <core/engctx.h> #include <core/event.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> #include <core/enum.h> #include <subdev/timer.h> @@ -216,46 +217,56 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct kepler_channel_gpfifo_a_v0 v0; + } *args = data; struct nouveau_bar *bar = nouveau_bar(parent); struct nve0_fifo_priv *priv = (void *)engine; struct nve0_fifo_base *base = (void *)parent; struct nve0_fifo_chan *chan; - struct nve0_channel_ind_class *args = data; u64 usermem, ioffset, ilength; int ret, i; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create channel gpfifo size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " + "ioffset %016llx ilength %08x engine %08x\n", + args->v0.version, args->v0.pushbuf, args->v0.ioffset, + args->v0.ilength, args->v0.engine); + } else + return ret; for (i = 0; i < FIFO_ENGINE_NR; i++) { - if (args->engine & (1 << i)) { + if (args->v0.engine & (1 << i)) { if (nouveau_engine(parent, fifo_engine[i].subdev)) { - args->engine = (1 << i); + args->v0.engine = (1 << i); break; } } } if (i == FIFO_ENGINE_NR) { - nv_error(priv, "unsupported engines 0x%08x\n", args->engine); + nv_error(priv, "unsupported engines 0x%08x\n", args->v0.engine); return -ENODEV; } ret = nouveau_fifo_channel_create(parent, engine, oclass, 1, priv->user.bar.offset, 0x200, - args->pushbuf, + args->v0.pushbuf, fifo_engine[i].mask, &chan); *pobject = nv_object(chan); if (ret) return ret; + args->v0.chid = chan->base.chid; + nv_parent(chan)->context_attach = nve0_fifo_context_attach; nv_parent(chan)->context_detach = nve0_fifo_context_detach; chan->engine = i; usermem = chan->base.chid * 0x200; - ioffset = args->ioffset; - ilength = order_base_2(args->ilength / 8); + ioffset = args->v0.ioffset; + ilength = order_base_2(args->v0.ilength / 8); for (i = 0; i < 0x200; i += 4) nv_wo32(priv->user.mem, usermem + i, 0x00000000); @@ -325,13 +336,15 @@ nve0_fifo_ofuncs = { .dtor = _nouveau_fifo_channel_dtor, .init = nve0_fifo_chan_init, .fini = nve0_fifo_chan_fini, + .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass nve0_fifo_sclass[] = { - { NVE0_CHANNEL_IND_CLASS, &nve0_fifo_ofuncs }, + { KEPLER_CHANNEL_GPFIFO_A, &nve0_fifo_ofuncs }, {} }; @@ -769,7 +782,7 @@ nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit) object = engctx; while (object) { switch (nv_mclass(object)) { - case NVE0_CHANNEL_IND_CLASS: + case KEPLER_CHANNEL_GPFIFO_A: nve0_fifo_recover(priv, engine, (void *)object); break; } @@ -859,7 +872,7 @@ nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv) static void nve0_fifo_intr_engine(struct nve0_fifo_priv *priv) { - nouveau_event_trigger(priv->base.uevent, 1, 0); + nouveau_fifo_uevent(&priv->base); } static void @@ -952,19 +965,26 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) } static void -nve0_fifo_uevent_enable(struct nouveau_event *event, int type, int index) +nve0_fifo_uevent_init(struct nvkm_event *event, int type, int index) { - struct nve0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x80000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x80000000, 0x80000000); } static void -nve0_fifo_uevent_disable(struct nouveau_event *event, int type, int index) +nve0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) { - struct nve0_fifo_priv *priv = event->priv; - nv_mask(priv, 0x002140, 0x80000000, 0x00000000); + struct nouveau_fifo *fifo = container_of(event, typeof(*fifo), uevent); + nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); } +static const struct nvkm_event_func +nve0_fifo_uevent_func = { + .ctor = nouveau_fifo_uevent_ctor, + .init = nve0_fifo_uevent_init, + .fini = nve0_fifo_uevent_fini, +}; + int nve0_fifo_fini(struct nouveau_object *object, bool suspend) { @@ -1067,9 +1087,9 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - priv->base.uevent->enable = nve0_fifo_uevent_enable; - priv->base.uevent->disable = nve0_fifo_uevent_disable; - priv->base.uevent->priv = priv; + ret = nvkm_event_init(&nve0_fifo_uevent_func, 1, 1, &priv->base.uevent); + if (ret) + return ret; nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nve0_fifo_intr; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk110b.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk110b.c new file mode 100644 index 000000000000..3adb7fe91772 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk110b.c @@ -0,0 +1,104 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ + +#include "ctxnvc0.h" + +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +gk110b_grctx_init_sm_0[] = { + { 0x419e04, 1, 0x04, 0x00000000 }, + { 0x419e08, 1, 0x04, 0x0000001d }, + { 0x419e0c, 1, 0x04, 0x00000000 }, + { 0x419e10, 1, 0x04, 0x00001c02 }, + { 0x419e44, 1, 0x04, 0x0013eff2 }, + { 0x419e48, 1, 0x04, 0x00000000 }, + { 0x419e4c, 1, 0x04, 0x0000007f }, + { 0x419e50, 2, 0x04, 0x00000000 }, + { 0x419e58, 1, 0x04, 0x00000001 }, + { 0x419e5c, 3, 0x04, 0x00000000 }, + { 0x419e68, 1, 0x04, 0x00000002 }, + { 0x419e6c, 12, 0x04, 0x00000000 }, + { 0x419eac, 1, 0x04, 0x00001f8f }, + { 0x419eb0, 1, 0x04, 0x0db00d2f }, + { 0x419eb8, 1, 0x04, 0x00000000 }, + { 0x419ec8, 1, 0x04, 0x0001304f }, + { 0x419f30, 4, 0x04, 0x00000000 }, + { 0x419f40, 1, 0x04, 0x00000018 }, + { 0x419f44, 3, 0x04, 0x00000000 }, + { 0x419f58, 1, 0x04, 0x00000000 }, + { 0x419f70, 1, 0x04, 0x00006300 }, + { 0x419f78, 1, 0x04, 0x000000eb }, + { 0x419f7c, 1, 0x04, 0x00000404 }, + {} +}; + +static const struct nvc0_graph_pack +gk110b_grctx_pack_tpc[] = { + { nvd7_grctx_init_pe_0 }, + { nvf0_grctx_init_tex_0 }, + { nvf0_grctx_init_mpc_0 }, + { nvf0_grctx_init_l1c_0 }, + { gk110b_grctx_init_sm_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + +struct nouveau_oclass * +gk110b_grctx_oclass = &(struct nvc0_grctx_oclass) { + .base.handle = NV_ENGCTX(GR, 0xf1), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_context_ctor, + .dtor = nvc0_graph_context_dtor, + .init = _nouveau_graph_context_init, + .fini = _nouveau_graph_context_fini, + .rd32 = _nouveau_graph_context_rd32, + .wr32 = _nouveau_graph_context_wr32, + }, + .main = nve4_grctx_generate_main, + .unkn = nve4_grctx_generate_unkn, + .hub = nvf0_grctx_pack_hub, + .gpc = nvf0_grctx_pack_gpc, + .zcull = nvc0_grctx_pack_zcull, + .tpc = gk110b_grctx_pack_tpc, + .ppc = nvf0_grctx_pack_ppc, + .icmd = nvf0_grctx_pack_icmd, + .mthd = nvf0_grctx_pack_mthd, + .bundle = nve4_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0x180, + .bundle_token_limit = 0x600, + .pagepool = nve4_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvd7_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x7ff, + .alpha_nr = 0x648, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c index 224ee0287ab7..36fc9831cc93 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c @@ -41,7 +41,6 @@ gk20a_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nve4_grctx_generate_main, - .mods = nve4_grctx_generate_mods, .unkn = nve4_grctx_generate_unkn, .hub = nve4_grctx_pack_hub, .gpc = nve4_grctx_pack_gpc, @@ -50,4 +49,15 @@ gk20a_grctx_oclass = &(struct nvc0_grctx_oclass) { .ppc = nve4_grctx_pack_ppc, .icmd = nve4_grctx_pack_icmd, .mthd = gk20a_grctx_pack_mthd, + .bundle = nve4_grctx_generate_bundle, + .bundle_size = 0x1800, + .bundle_min_gpm_fifo_depth = 0x62, + .bundle_token_limit = 0x100, + .pagepool = nve4_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvd7_grctx_generate_attrib, + .attrib_nr_max = 0x240, + .attrib_nr = 0x240, + .alpha_nr_max = 0x648 + (0x648 / 2), + .alpha_nr = 0x648, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c index b0d0fb2f4d08..62e918b9fa81 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c @@ -859,45 +859,74 @@ gm107_grctx_pack_ppc[] = { ******************************************************************************/ static void -gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +gm107_grctx_generate_bundle(struct nvc0_grctx *info) { - mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x200000, 0x1000, NV_MEM_ACCESS_RW); - - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x4064cc, 0x80000000, 0, 0); - mmio_list(0x418e30, 0x80000000, 0, 0); - - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000030, 0, 0); - mmio_list(0x418e24, 0x00000000, 8, 0); - mmio_list(0x418e28, 0x80000030, 0, 0); - - mmio_list(0x4064c8, 0x018002c0, 0, 0); - - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); - mmio_list(0x419c2c, 0x10000000, 12, 2); - - mmio_list(0x405830, 0x0aa01000, 0, 0); - mmio_list(0x4064c4, 0x0400ffff, 0, 0); - - /*XXX*/ - mmio_list(0x5030c0, 0x00001540, 0, 0); - mmio_list(0x5030f4, 0x00000000, 0, 0); - mmio_list(0x5030e4, 0x00002000, 0, 0); - mmio_list(0x5030f8, 0x00003fc0, 0, 0); - mmio_list(0x418ea0, 0x07151540, 0, 0); - - mmio_list(0x5032c0, 0x00001540, 0, 0); - mmio_list(0x5032f4, 0x00001fe0, 0, 0); - mmio_list(0x5032e4, 0x00002000, 0, 0); - mmio_list(0x5032f8, 0x00006fc0, 0, 0); - mmio_list(0x418ea4, 0x07151540, 0, 0); + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv); + const u32 state_limit = min(impl->bundle_min_gpm_fifo_depth, + impl->bundle_size / 0x20); + const u32 token_limit = impl->bundle_token_limit; + const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; + const int s = 8; + const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); + mmio_refn(info, 0x408004, 0x00000000, s, b); + mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b); + mmio_refn(info, 0x418e24, 0x00000000, s, b); + mmio_refn(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s), 0, b); + mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit); +} + +static void +gm107_grctx_generate_pagepool(struct nvc0_grctx *info) +{ + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv); + const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; + const int s = 8; + const int b = mmio_vram(info, impl->pagepool_size, (1 << s), access); + mmio_refn(info, 0x40800c, 0x00000000, s, b); + mmio_wr32(info, 0x408010, 0x80000000); + mmio_refn(info, 0x419004, 0x00000000, s, b); + mmio_wr32(info, 0x419008, 0x00000000); + mmio_wr32(info, 0x4064cc, 0x80000000); + mmio_wr32(info, 0x418e30, 0x80000000); /* guess at it being related */ +} + +static void +gm107_grctx_generate_attrib(struct nvc0_grctx *info) +{ + struct nvc0_graph_priv *priv = info->priv; + const struct nvc0_grctx_oclass *impl = (void *)nvc0_grctx_impl(priv); + const u32 alpha = impl->alpha_nr; + const u32 attrib = impl->attrib_nr; + const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max); + const u32 access = NV_MEM_ACCESS_RW; + const int s = 12; + const int b = mmio_vram(info, size * priv->tpc_total, (1 << s), access); + const int max_batches = 0xffff; + u32 bo = 0; + u32 ao = bo + impl->attrib_nr_max * priv->tpc_total; + int gpc, ppc, n = 0; + + mmio_refn(info, 0x418810, 0x80000000, s, b); + mmio_refn(info, 0x419848, 0x10000000, s, b); + mmio_refn(info, 0x419c2c, 0x10000000, s, b); + mmio_wr32(info, 0x405830, (attrib << 16) | alpha); + mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + for (ppc = 0; ppc < priv->ppc_nr[gpc]; ppc++, n++) { + const u32 as = alpha * priv->ppc_tpc_nr[gpc][ppc]; + const u32 bs = attrib * priv->ppc_tpc_nr[gpc][ppc]; + const u32 u = 0x418ea0 + (n * 0x04); + const u32 o = PPC_UNIT(gpc, ppc, 0); + mmio_wr32(info, o + 0xc0, bs); + mmio_wr32(info, o + 0xf4, bo); + bo += impl->attrib_nr_max * priv->ppc_tpc_nr[gpc][ppc]; + mmio_wr32(info, o + 0xe4, as); + mmio_wr32(info, o + 0xf8, ao); + ao += impl->alpha_nr_max * priv->ppc_tpc_nr[gpc][ppc]; + mmio_wr32(info, u, (0x715 /*XXX*/ << 16) | bs); + } + } } static void @@ -934,7 +963,9 @@ gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_wr32(priv, 0x404154, 0x00000000); - oclass->mods(priv, info); + oclass->bundle(info); + oclass->pagepool(info); + oclass->attrib(info); oclass->unkn(priv); gm107_grctx_generate_tpcid(priv); @@ -979,7 +1010,6 @@ gm107_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = gm107_grctx_generate_main, - .mods = gm107_grctx_generate_mods, .unkn = nve4_grctx_generate_unkn, .hub = gm107_grctx_pack_hub, .gpc = gm107_grctx_pack_gpc, @@ -988,4 +1018,15 @@ gm107_grctx_oclass = &(struct nvc0_grctx_oclass) { .ppc = gm107_grctx_pack_ppc, .icmd = gm107_grctx_pack_icmd, .mthd = gm107_grctx_pack_mthd, + .bundle = gm107_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0x180, + .bundle_token_limit = 0x2c0, + .pagepool = gm107_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = gm107_grctx_generate_attrib, + .attrib_nr_max = 0xff0, + .attrib_nr = 0xaa0, + .alpha_nr_max = 0x1800, + .alpha_nr = 0x1000, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c index 8de4a4291548..ce252adbef81 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c @@ -531,50 +531,6 @@ nv108_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ -static void -nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) -{ - u32 magic[GPC_MAX][2]; - u32 offset; - int gpc; - - mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x4064cc, 0x80000000, 0, 0); - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000030, 0, 0); - mmio_list(0x418808, 0x00000000, 8, 0); - mmio_list(0x41880c, 0x80000030, 0, 0); - mmio_list(0x4064c8, 0x00c20200, 0, 0); - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); - - mmio_list(0x405830, 0x02180648, 0, 0); - mmio_list(0x4064c4, 0x0192ffff, 0, 0); - - for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { - u16 magic0 = 0x0218 * priv->tpc_nr[gpc]; - u16 magic1 = 0x0648 * priv->tpc_nr[gpc]; - magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset; - magic[gpc][1] = 0x00000000 | (magic1 << 16); - offset += 0x0324 * priv->tpc_nr[gpc]; - } - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0); - mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0); - offset += 0x07ff * priv->tpc_nr[gpc]; - } - - mmio_list(0x17e91c, 0x0b040a0b, 0, 0); - mmio_list(0x17e920, 0x00090d08, 0, 0); -} - struct nouveau_oclass * nv108_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0x08), @@ -587,7 +543,6 @@ nv108_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nve4_grctx_generate_main, - .mods = nv108_grctx_generate_mods, .unkn = nve4_grctx_generate_unkn, .hub = nv108_grctx_pack_hub, .gpc = nv108_grctx_pack_gpc, @@ -596,4 +551,15 @@ nv108_grctx_oclass = &(struct nvc0_grctx_oclass) { .ppc = nv108_grctx_pack_ppc, .icmd = nv108_grctx_pack_icmd, .mthd = nvf0_grctx_pack_mthd, + .bundle = nve4_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0xc2, + .bundle_token_limit = 0x200, + .pagepool = nve4_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvd7_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x7ff, + .alpha_nr = 0x648, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c index 833a96508c4e..b8e5fe60a1eb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c @@ -982,34 +982,93 @@ nvc0_grctx_pack_tpc[] = { * PGRAPH context implementation ******************************************************************************/ +int +nvc0_grctx_mmio_data(struct nvc0_grctx *info, u32 size, u32 align, u32 access) +{ + if (info->data) { + info->buffer[info->buffer_nr] = round_up(info->addr, align); + info->addr = info->buffer[info->buffer_nr] + size; + info->data->size = size; + info->data->align = align; + info->data->access = access; + info->data++; + return info->buffer_nr++; + } + return -1; +} + +void +nvc0_grctx_mmio_item(struct nvc0_grctx *info, u32 addr, u32 data, + int shift, int buffer) +{ + if (info->data) { + if (shift >= 0) { + info->mmio->addr = addr; + info->mmio->data = data; + info->mmio->shift = shift; + info->mmio->buffer = buffer; + if (buffer >= 0) + data |= info->buffer[buffer] >> shift; + info->mmio++; + } else + return; + } else { + if (buffer >= 0) + return; + } + + nv_wr32(info->priv, addr, data); +} + +void +nvc0_grctx_generate_bundle(struct nvc0_grctx *info) +{ + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv); + const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; + const int s = 8; + const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); + mmio_refn(info, 0x408004, 0x00000000, s, b); + mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b); + mmio_refn(info, 0x418808, 0x00000000, s, b); + mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b); +} + void -nvc0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +nvc0_grctx_generate_pagepool(struct nvc0_grctx *info) { + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv); + const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; + const int s = 8; + const int b = mmio_vram(info, impl->pagepool_size, (1 << s), access); + mmio_refn(info, 0x40800c, 0x00000000, s, b); + mmio_wr32(info, 0x408010, 0x80000000); + mmio_refn(info, 0x419004, 0x00000000, s, b); + mmio_wr32(info, 0x419008, 0x00000000); +} + +void +nvc0_grctx_generate_attrib(struct nvc0_grctx *info) +{ + struct nvc0_graph_priv *priv = info->priv; + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(priv); + const u32 attrib = impl->attrib_nr; + const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max); + const u32 access = NV_MEM_ACCESS_RW; + const int s = 12; + const int b = mmio_vram(info, size * priv->tpc_total, (1 << s), access); int gpc, tpc; - u32 offset; - - mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); - - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000018, 0, 0); - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x418808, 0x00000000, 8, 0); - mmio_list(0x41880c, 0x80000018, 0, 0); - - mmio_list(0x405830, 0x02180000, 0, 0); - - for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { + u32 bo = 0; + + mmio_refn(info, 0x418810, 0x80000000, s, b); + mmio_refn(info, 0x419848, 0x10000000, s, b); + mmio_wr32(info, 0x405830, (attrib << 16)); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { - u32 addr = TPC_UNIT(gpc, tpc, 0x0520); - mmio_list(addr, 0x02180000 | offset, 0, 0); - offset += 0x0324; + const u32 o = TPC_UNIT(gpc, tpc, 0x0520); + mmio_skip(info, o, (attrib << 16) | ++bo); + mmio_wr32(info, o, (attrib << 16) | --bo); + bo += impl->attrib_nr_max; } } } @@ -1170,7 +1229,7 @@ nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass; - nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 0); nvc0_graph_mmio(priv, oclass->hub); nvc0_graph_mmio(priv, oclass->gpc); @@ -1180,7 +1239,9 @@ nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_wr32(priv, 0x404154, 0x00000000); - oclass->mods(priv, info); + oclass->bundle(info); + oclass->pagepool(info); + oclass->attrib(info); oclass->unkn(priv); nvc0_grctx_generate_tpcid(priv); @@ -1192,7 +1253,7 @@ nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nvc0_graph_icmd(priv, oclass->icmd); nv_wr32(priv, 0x404154, 0x00000400); nvc0_graph_mthd(priv, oclass->mthd); - nv_mask(priv, 0x000260, 0x00000001, 0x00000001); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 1); } int @@ -1308,7 +1369,6 @@ nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nvc0_grctx_generate_main, - .mods = nvc0_grctx_generate_mods, .unkn = nvc0_grctx_generate_unkn, .hub = nvc0_grctx_pack_hub, .gpc = nvc0_grctx_pack_gpc, @@ -1316,4 +1376,11 @@ nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) { .tpc = nvc0_grctx_pack_tpc, .icmd = nvc0_grctx_pack_icmd, .mthd = nvc0_grctx_pack_mthd, + .bundle = nvc0_grctx_generate_bundle, + .bundle_size = 0x1800, + .pagepool = nvc0_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvc0_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h index 8da8b627b9d0..c776cd715e33 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h @@ -12,12 +12,19 @@ struct nvc0_grctx { u64 addr; }; +int nvc0_grctx_mmio_data(struct nvc0_grctx *, u32 size, u32 align, u32 access); +void nvc0_grctx_mmio_item(struct nvc0_grctx *, u32 addr, u32 data, int s, int); + +#define mmio_vram(a,b,c,d) nvc0_grctx_mmio_data((a), (b), (c), (d)) +#define mmio_refn(a,b,c,d,e) nvc0_grctx_mmio_item((a), (b), (c), (d), (e)) +#define mmio_skip(a,b,c) mmio_refn((a), (b), (c), -1, -1) +#define mmio_wr32(a,b,c) mmio_refn((a), (b), (c), 0, -1) + struct nvc0_grctx_oclass { struct nouveau_oclass base; /* main context generation function */ void (*main)(struct nvc0_graph_priv *, struct nvc0_grctx *); /* context-specific modify-on-first-load list generation function */ - void (*mods)(struct nvc0_graph_priv *, struct nvc0_grctx *); void (*unkn)(struct nvc0_graph_priv *); /* mmio context data */ const struct nvc0_graph_pack *hub; @@ -28,30 +35,34 @@ struct nvc0_grctx_oclass { /* indirect context data, generated with icmds/mthds */ const struct nvc0_graph_pack *icmd; const struct nvc0_graph_pack *mthd; + /* bundle circular buffer */ + void (*bundle)(struct nvc0_grctx *); + u32 bundle_size; + u32 bundle_min_gpm_fifo_depth; + u32 bundle_token_limit; + /* pagepool */ + void (*pagepool)(struct nvc0_grctx *); + u32 pagepool_size; + /* attribute(/alpha) circular buffer */ + void (*attrib)(struct nvc0_grctx *); + u32 attrib_nr_max; + u32 attrib_nr; + u32 alpha_nr_max; + u32 alpha_nr; }; -#define mmio_data(s,a,p) do { \ - info->buffer[info->buffer_nr] = round_up(info->addr, (a)); \ - info->addr = info->buffer[info->buffer_nr++] + (s); \ - info->data->size = (s); \ - info->data->align = (a); \ - info->data->access = (p); \ - info->data++; \ -} while(0) - -#define mmio_list(r,d,s,b) do { \ - info->mmio->addr = (r); \ - info->mmio->data = (d); \ - info->mmio->shift = (s); \ - info->mmio->buffer = (b); \ - info->mmio++; \ - nv_wr32(priv, (r), (d) | ((s) ? (info->buffer[(b)] >> (s)) : 0)); \ -} while(0) +static inline const struct nvc0_grctx_oclass * +nvc0_grctx_impl(struct nvc0_graph_priv *priv) +{ + return (void *)nv_engine(priv)->cclass; +} extern struct nouveau_oclass *nvc0_grctx_oclass; int nvc0_grctx_generate(struct nvc0_graph_priv *); void nvc0_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *); -void nvc0_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *); +void nvc0_grctx_generate_bundle(struct nvc0_grctx *); +void nvc0_grctx_generate_pagepool(struct nvc0_grctx *); +void nvc0_grctx_generate_attrib(struct nvc0_grctx *); void nvc0_grctx_generate_unkn(struct nvc0_graph_priv *); void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *); void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *); @@ -60,22 +71,27 @@ void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *); void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *); extern struct nouveau_oclass *nvc1_grctx_oclass; -void nvc1_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *); +void nvc1_grctx_generate_attrib(struct nvc0_grctx *); void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *); extern struct nouveau_oclass *nvc4_grctx_oclass; extern struct nouveau_oclass *nvc8_grctx_oclass; + extern struct nouveau_oclass *nvd7_grctx_oclass; +void nvd7_grctx_generate_attrib(struct nvc0_grctx *); + extern struct nouveau_oclass *nvd9_grctx_oclass; extern struct nouveau_oclass *nve4_grctx_oclass; extern struct nouveau_oclass *gk20a_grctx_oclass; void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *); -void nve4_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *); +void nve4_grctx_generate_bundle(struct nvc0_grctx *); +void nve4_grctx_generate_pagepool(struct nvc0_grctx *); void nve4_grctx_generate_unkn(struct nvc0_graph_priv *); void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *); extern struct nouveau_oclass *nvf0_grctx_oclass; +extern struct nouveau_oclass *gk110b_grctx_oclass; extern struct nouveau_oclass *nv108_grctx_oclass; extern struct nouveau_oclass *gm107_grctx_oclass; @@ -160,16 +176,23 @@ extern const struct nvc0_graph_pack nve4_grctx_pack_ppc[]; extern const struct nvc0_graph_pack nve4_grctx_pack_icmd[]; extern const struct nvc0_graph_init nve4_grctx_init_a097_0[]; +extern const struct nvc0_graph_pack nvf0_grctx_pack_icmd[]; + extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[]; +extern const struct nvc0_graph_pack nvf0_grctx_pack_hub[]; extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[]; extern const struct nvc0_graph_init nvf0_grctx_init_cwd_0[]; +extern const struct nvc0_graph_pack nvf0_grctx_pack_gpc[]; extern const struct nvc0_graph_init nvf0_grctx_init_gpc_unk_2[]; +extern const struct nvc0_graph_init nvf0_grctx_init_tex_0[]; extern const struct nvc0_graph_init nvf0_grctx_init_mpc_0[]; extern const struct nvc0_graph_init nvf0_grctx_init_l1c_0[]; +extern const struct nvc0_graph_pack nvf0_grctx_pack_ppc[]; + extern const struct nvc0_graph_init nv108_grctx_init_rstr2d_0[]; extern const struct nvc0_graph_init nv108_grctx_init_prop_0[]; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c index 24a92c569c0a..c6ba8fed18f1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c @@ -727,38 +727,38 @@ nvc1_grctx_pack_tpc[] = { ******************************************************************************/ void -nvc1_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +nvc1_grctx_generate_attrib(struct nvc0_grctx *info) { + struct nvc0_graph_priv *priv = info->priv; + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(priv); + const u32 alpha = impl->alpha_nr; + const u32 beta = impl->attrib_nr; + const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max); + const u32 access = NV_MEM_ACCESS_RW; + const int s = 12; + const int b = mmio_vram(info, size * priv->tpc_total, (1 << s), access); + const int timeslice_mode = 1; + const int max_batches = 0xffff; + u32 bo = 0; + u32 ao = bo + impl->attrib_nr_max * priv->tpc_total; int gpc, tpc; - u32 offset; - mmio_data(0x002000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000018, 0, 0); - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x418808, 0x00000000, 8, 0); - mmio_list(0x41880c, 0x80000018, 0, 0); + mmio_refn(info, 0x418810, 0x80000000, s, b); + mmio_refn(info, 0x419848, 0x10000000, s, b); + mmio_wr32(info, 0x405830, (beta << 16) | alpha); + mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches); - mmio_list(0x405830, 0x02180218, 0, 0); - mmio_list(0x4064c4, 0x0086ffff, 0, 0); - - for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { - for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { - u32 addr = TPC_UNIT(gpc, tpc, 0x0520); - mmio_list(addr, 0x12180000 | offset, 0, 0); - offset += 0x0324; - } + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { - u32 addr = TPC_UNIT(gpc, tpc, 0x0544); - mmio_list(addr, 0x02180000 | offset, 0, 0); - offset += 0x0324; + const u32 a = alpha; + const u32 b = beta; + const u32 t = timeslice_mode; + const u32 o = TPC_UNIT(gpc, tpc, 0x500); + mmio_skip(info, o + 0x20, (t << 28) | (b << 16) | ++bo); + mmio_wr32(info, o + 0x20, (t << 28) | (b << 16) | --bo); + bo += impl->attrib_nr_max; + mmio_wr32(info, o + 0x44, (a << 16) | ao); + ao += impl->alpha_nr_max; } } } @@ -786,7 +786,6 @@ nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nvc0_grctx_generate_main, - .mods = nvc1_grctx_generate_mods, .unkn = nvc1_grctx_generate_unkn, .hub = nvc1_grctx_pack_hub, .gpc = nvc1_grctx_pack_gpc, @@ -794,4 +793,13 @@ nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) { .tpc = nvc1_grctx_pack_tpc, .icmd = nvc1_grctx_pack_icmd, .mthd = nvc1_grctx_pack_mthd, + .bundle = nvc0_grctx_generate_bundle, + .bundle_size = 0x1800, + .pagepool = nvc0_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvc1_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x324, + .alpha_nr = 0x218, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c index e11ed5538193..41705c60cc47 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c @@ -92,7 +92,6 @@ nvc4_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nvc0_grctx_generate_main, - .mods = nvc0_grctx_generate_mods, .unkn = nvc0_grctx_generate_unkn, .hub = nvc0_grctx_pack_hub, .gpc = nvc0_grctx_pack_gpc, @@ -100,4 +99,11 @@ nvc4_grctx_oclass = &(struct nvc0_grctx_oclass) { .tpc = nvc4_grctx_pack_tpc, .icmd = nvc0_grctx_pack_icmd, .mthd = nvc0_grctx_pack_mthd, + .bundle = nvc0_grctx_generate_bundle, + .bundle_size = 0x1800, + .pagepool = nvc0_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvc0_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c index feebd58dfe8d..8f804cd8f9c7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c @@ -343,7 +343,6 @@ nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nvc0_grctx_generate_main, - .mods = nvc0_grctx_generate_mods, .unkn = nvc0_grctx_generate_unkn, .hub = nvc0_grctx_pack_hub, .gpc = nvc8_grctx_pack_gpc, @@ -351,4 +350,11 @@ nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) { .tpc = nvc0_grctx_pack_tpc, .icmd = nvc8_grctx_pack_icmd, .mthd = nvc8_grctx_pack_mthd, + .bundle = nvc0_grctx_generate_bundle, + .bundle_size = 0x1800, + .pagepool = nvc0_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvc0_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c index 1dbc8d7f2e86..fcf534fd9e65 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c @@ -177,44 +177,41 @@ nvd7_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ -static void -nvd7_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +void +nvd7_grctx_generate_attrib(struct nvc0_grctx *info) { - u32 magic[GPC_MAX][2]; - u32 offset; - int gpc; - - mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000018, 0, 0); - mmio_list(0x418808, 0x00000000, 8, 0); - mmio_list(0x41880c, 0x80000018, 0, 0); - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); + struct nvc0_graph_priv *priv = info->priv; + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(priv); + const u32 alpha = impl->alpha_nr; + const u32 beta = impl->attrib_nr; + const u32 size = 0x20 * (impl->attrib_nr_max + impl->alpha_nr_max); + const u32 access = NV_MEM_ACCESS_RW; + const int s = 12; + const int b = mmio_vram(info, size * priv->tpc_total, (1 << s), access); + const int timeslice_mode = 1; + const int max_batches = 0xffff; + u32 bo = 0; + u32 ao = bo + impl->attrib_nr_max * priv->tpc_total; + int gpc, ppc; - mmio_list(0x405830, 0x02180324, 0, 0); - mmio_list(0x4064c4, 0x00c9ffff, 0, 0); - - for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { - u16 magic0 = 0x0218 * priv->tpc_nr[gpc]; - u16 magic1 = 0x0324 * priv->tpc_nr[gpc]; - magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset; - magic[gpc][1] = 0x00000000 | (magic1 << 16); - offset += 0x0324 * priv->tpc_nr[gpc]; - } + mmio_refn(info, 0x418810, 0x80000000, s, b); + mmio_refn(info, 0x419848, 0x10000000, s, b); + mmio_wr32(info, 0x405830, (beta << 16) | alpha); + mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches); for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0); - mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0); - offset += 0x07ff * priv->tpc_nr[gpc]; + for (ppc = 0; ppc < priv->ppc_nr[gpc]; ppc++) { + const u32 a = alpha * priv->ppc_tpc_nr[gpc][ppc]; + const u32 b = beta * priv->ppc_tpc_nr[gpc][ppc]; + const u32 t = timeslice_mode; + const u32 o = PPC_UNIT(gpc, ppc, 0); + mmio_skip(info, o + 0xc0, (t << 28) | (b << 16) | ++bo); + mmio_wr32(info, o + 0xc0, (t << 28) | (b << 16) | --bo); + bo += impl->attrib_nr_max * priv->ppc_tpc_nr[gpc][ppc]; + mmio_wr32(info, o + 0xe4, (a << 16) | ao); + ao += impl->alpha_nr_max * priv->ppc_tpc_nr[gpc][ppc]; + } } - mmio_list(0x17e91c, 0x03060609, 0, 0); /* different from kepler */ } void @@ -223,7 +220,7 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass; int i; - nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 0); nvc0_graph_mmio(priv, oclass->hub); nvc0_graph_mmio(priv, oclass->gpc); @@ -233,7 +230,9 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_wr32(priv, 0x404154, 0x00000000); - oclass->mods(priv, info); + oclass->bundle(info); + oclass->pagepool(info); + oclass->attrib(info); oclass->unkn(priv); nvc0_grctx_generate_tpcid(priv); @@ -248,7 +247,7 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nvc0_graph_icmd(priv, oclass->icmd); nv_wr32(priv, 0x404154, 0x00000400); nvc0_graph_mthd(priv, oclass->mthd); - nv_mask(priv, 0x000260, 0x00000001, 0x00000001); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 1); } struct nouveau_oclass * @@ -263,7 +262,6 @@ nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nvd7_grctx_generate_main, - .mods = nvd7_grctx_generate_mods, .unkn = nve4_grctx_generate_unkn, .hub = nvd7_grctx_pack_hub, .gpc = nvd7_grctx_pack_gpc, @@ -272,4 +270,13 @@ nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) { .ppc = nvd7_grctx_pack_ppc, .icmd = nvd9_grctx_pack_icmd, .mthd = nvd9_grctx_pack_mthd, + .bundle = nvc0_grctx_generate_bundle, + .bundle_size = 0x1800, + .pagepool = nvc0_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvd7_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x7ff, + .alpha_nr = 0x324, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c index c665fb7e4660..b9a301b6fd9f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c @@ -511,7 +511,6 @@ nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nvc0_grctx_generate_main, - .mods = nvc1_grctx_generate_mods, .unkn = nvc1_grctx_generate_unkn, .hub = nvd9_grctx_pack_hub, .gpc = nvd9_grctx_pack_gpc, @@ -519,4 +518,13 @@ nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) { .tpc = nvd9_grctx_pack_tpc, .icmd = nvd9_grctx_pack_icmd, .mthd = nvd9_grctx_pack_mthd, + .bundle = nvc0_grctx_generate_bundle, + .bundle_size = 0x1800, + .pagepool = nvc0_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvc1_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x324, + .alpha_nr = 0x218, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c index c5b249238587..ccac2ee1a1cb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c @@ -839,47 +839,34 @@ nve4_grctx_pack_ppc[] = { ******************************************************************************/ void -nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +nve4_grctx_generate_bundle(struct nvc0_grctx *info) { - u32 magic[GPC_MAX][2]; - u32 offset; - int gpc; - - mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x4064cc, 0x80000000, 0, 0); - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000030, 0, 0); - mmio_list(0x418808, 0x00000000, 8, 0); - mmio_list(0x41880c, 0x80000030, 0, 0); - mmio_list(0x4064c8, 0x01800600, 0, 0); - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); - - mmio_list(0x405830, 0x02180648, 0, 0); - mmio_list(0x4064c4, 0x0192ffff, 0, 0); - - for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { - u16 magic0 = 0x0218 * priv->tpc_nr[gpc]; - u16 magic1 = 0x0648 * priv->tpc_nr[gpc]; - magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset; - magic[gpc][1] = 0x00000000 | (magic1 << 16); - offset += 0x0324 * priv->tpc_nr[gpc]; - } - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0); - mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0); - offset += 0x07ff * priv->tpc_nr[gpc]; - } + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv); + const u32 state_limit = min(impl->bundle_min_gpm_fifo_depth, + impl->bundle_size / 0x20); + const u32 token_limit = impl->bundle_token_limit; + const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; + const int s = 8; + const int b = mmio_vram(info, impl->bundle_size, (1 << s), access); + mmio_refn(info, 0x408004, 0x00000000, s, b); + mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b); + mmio_refn(info, 0x418808, 0x00000000, s, b); + mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b); + mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit); +} - mmio_list(0x17e91c, 0x06060609, 0, 0); - mmio_list(0x17e920, 0x00090a05, 0, 0); +void +nve4_grctx_generate_pagepool(struct nvc0_grctx *info) +{ + const struct nvc0_grctx_oclass *impl = nvc0_grctx_impl(info->priv); + const u32 access = NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS; + const int s = 8; + const int b = mmio_vram(info, impl->pagepool_size, (1 << s), access); + mmio_refn(info, 0x40800c, 0x00000000, s, b); + mmio_wr32(info, 0x408010, 0x80000000); + mmio_refn(info, 0x419004, 0x00000000, s, b); + mmio_wr32(info, 0x419008, 0x00000000); + mmio_wr32(info, 0x4064cc, 0x80000000); } void @@ -957,7 +944,7 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass; int i; - nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 0); nvc0_graph_mmio(priv, oclass->hub); nvc0_graph_mmio(priv, oclass->gpc); @@ -967,7 +954,9 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_wr32(priv, 0x404154, 0x00000000); - oclass->mods(priv, info); + oclass->bundle(info); + oclass->pagepool(info); + oclass->attrib(info); oclass->unkn(priv); nvc0_grctx_generate_tpcid(priv); @@ -991,7 +980,7 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nvc0_graph_icmd(priv, oclass->icmd); nv_wr32(priv, 0x404154, 0x00000400); nvc0_graph_mthd(priv, oclass->mthd); - nv_mask(priv, 0x000260, 0x00000001, 0x00000001); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 1); nv_mask(priv, 0x418800, 0x00200000, 0x00200000); nv_mask(priv, 0x41be10, 0x00800000, 0x00800000); @@ -1009,7 +998,6 @@ nve4_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nve4_grctx_generate_main, - .mods = nve4_grctx_generate_mods, .unkn = nve4_grctx_generate_unkn, .hub = nve4_grctx_pack_hub, .gpc = nve4_grctx_pack_gpc, @@ -1018,4 +1006,15 @@ nve4_grctx_oclass = &(struct nvc0_grctx_oclass) { .ppc = nve4_grctx_pack_ppc, .icmd = nve4_grctx_pack_icmd, .mthd = nve4_grctx_pack_mthd, + .bundle = nve4_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0x180, + .bundle_token_limit = 0x600, + .pagepool = nve4_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvd7_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x7ff, + .alpha_nr = 0x648, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c index dec03f04114d..e9b0dcf95a49 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c @@ -279,7 +279,7 @@ nvf0_grctx_init_icmd_0[] = { {} }; -static const struct nvc0_graph_pack +const struct nvc0_graph_pack nvf0_grctx_pack_icmd[] = { { nvf0_grctx_init_icmd_0 }, {} @@ -668,7 +668,7 @@ nvf0_grctx_init_be_0[] = { {} }; -static const struct nvc0_graph_pack +const struct nvc0_graph_pack nvf0_grctx_pack_hub[] = { { nvc0_grctx_init_main_0 }, { nvf0_grctx_init_fe_0 }, @@ -704,7 +704,7 @@ nvf0_grctx_init_gpc_unk_2[] = { {} }; -static const struct nvc0_graph_pack +const struct nvc0_graph_pack nvf0_grctx_pack_gpc[] = { { nvc0_grctx_init_gpc_unk_0 }, { nvd9_grctx_init_prop_0 }, @@ -718,7 +718,7 @@ nvf0_grctx_pack_gpc[] = { {} }; -static const struct nvc0_graph_init +const struct nvc0_graph_init nvf0_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000000f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, @@ -797,7 +797,7 @@ nvf0_grctx_init_cbm_0[] = { {} }; -static const struct nvc0_graph_pack +const struct nvc0_graph_pack nvf0_grctx_pack_ppc[] = { { nve4_grctx_init_pes_0 }, { nvf0_grctx_init_cbm_0 }, @@ -809,58 +809,6 @@ nvf0_grctx_pack_ppc[] = { * PGRAPH context implementation ******************************************************************************/ -static void -nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) -{ - u32 magic[GPC_MAX][4]; - u32 offset; - int gpc; - - mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); - mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); - mmio_list(0x40800c, 0x00000000, 8, 1); - mmio_list(0x408010, 0x80000000, 0, 0); - mmio_list(0x419004, 0x00000000, 8, 1); - mmio_list(0x419008, 0x00000000, 0, 0); - mmio_list(0x4064cc, 0x80000000, 0, 0); - mmio_list(0x408004, 0x00000000, 8, 0); - mmio_list(0x408008, 0x80000030, 0, 0); - mmio_list(0x418808, 0x00000000, 8, 0); - mmio_list(0x41880c, 0x80000030, 0, 0); - mmio_list(0x4064c8, 0x01800600, 0, 0); - mmio_list(0x418810, 0x80000000, 12, 2); - mmio_list(0x419848, 0x10000000, 12, 2); - - mmio_list(0x405830, 0x02180648, 0, 0); - mmio_list(0x4064c4, 0x0192ffff, 0, 0); - - for (gpc = 0, offset = 0; gpc < priv->gpc_nr; gpc++) { - u16 magic0 = 0x0218 * (priv->tpc_nr[gpc] - 1); - u16 magic1 = 0x0648 * (priv->tpc_nr[gpc] - 1); - u16 magic2 = 0x0218; - u16 magic3 = 0x0648; - magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset; - magic[gpc][1] = 0x00000000 | (magic1 << 16); - offset += 0x0324 * (priv->tpc_nr[gpc] - 1); - magic[gpc][2] = 0x10000000 | (magic2 << 16) | offset; - magic[gpc][3] = 0x00000000 | (magic3 << 16); - offset += 0x0324; - } - - for (gpc = 0; gpc < priv->gpc_nr; gpc++) { - mmio_list(GPC_UNIT(gpc, 0x30c0), magic[gpc][0], 0, 0); - mmio_list(GPC_UNIT(gpc, 0x30e4), magic[gpc][1] | offset, 0, 0); - offset += 0x07ff * (priv->tpc_nr[gpc] - 1); - mmio_list(GPC_UNIT(gpc, 0x32c0), magic[gpc][2], 0, 0); - mmio_list(GPC_UNIT(gpc, 0x32e4), magic[gpc][3] | offset, 0, 0); - offset += 0x07ff; - } - - mmio_list(0x17e91c, 0x06060609, 0, 0); - mmio_list(0x17e920, 0x00090a05, 0, 0); -} - struct nouveau_oclass * nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xf0), @@ -873,7 +821,6 @@ nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) { .wr32 = _nouveau_graph_context_wr32, }, .main = nve4_grctx_generate_main, - .mods = nvf0_grctx_generate_mods, .unkn = nve4_grctx_generate_unkn, .hub = nvf0_grctx_pack_hub, .gpc = nvf0_grctx_pack_gpc, @@ -882,4 +829,15 @@ nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) { .ppc = nvf0_grctx_pack_ppc, .icmd = nvf0_grctx_pack_icmd, .mthd = nvf0_grctx_pack_mthd, + .bundle = nve4_grctx_generate_bundle, + .bundle_size = 0x3000, + .bundle_min_gpm_fifo_depth = 0x180, + .bundle_token_limit = 0x7c0, + .pagepool = nve4_grctx_generate_pagepool, + .pagepool_size = 0x8000, + .attrib = nvd7_grctx_generate_attrib, + .attrib_nr_max = 0x324, + .attrib_nr = 0x218, + .alpha_nr_max = 0x7ff, + .alpha_nr = 0x648, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gk110b.c b/drivers/gpu/drm/nouveau/core/engine/graph/gk110b.c new file mode 100644 index 000000000000..d07b19dc168d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/gk110b.c @@ -0,0 +1,117 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs <bskeggs@redhat.com> + */ + +#include "nvc0.h" +#include "ctxnvc0.h" + +/******************************************************************************* + * PGRAPH register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +gk110b_graph_init_l1c_0[] = { + { 0x419c98, 1, 0x04, 0x00000000 }, + { 0x419ca8, 1, 0x04, 0x00000000 }, + { 0x419cb0, 1, 0x04, 0x09000000 }, + { 0x419cb4, 1, 0x04, 0x00000000 }, + { 0x419cb8, 1, 0x04, 0x00b08bea }, + { 0x419c84, 1, 0x04, 0x00010384 }, + { 0x419cbc, 1, 0x04, 0x281b3646 }, + { 0x419cc0, 2, 0x04, 0x00000000 }, + { 0x419c80, 1, 0x04, 0x00020230 }, + { 0x419ccc, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gk110b_graph_init_sm_0[] = { + { 0x419e00, 1, 0x04, 0x00000080 }, + { 0x419ea0, 1, 0x04, 0x00000000 }, + { 0x419ee4, 1, 0x04, 0x00000000 }, + { 0x419ea4, 1, 0x04, 0x00000100 }, + { 0x419ea8, 1, 0x04, 0x00000000 }, + { 0x419eb4, 1, 0x04, 0x00000000 }, + { 0x419ebc, 2, 0x04, 0x00000000 }, + { 0x419edc, 1, 0x04, 0x00000000 }, + { 0x419f00, 1, 0x04, 0x00000000 }, + { 0x419ed0, 1, 0x04, 0x00002616 }, + { 0x419f74, 1, 0x04, 0x00015555 }, + { 0x419f80, 4, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +gk110b_graph_pack_mmio[] = { + { nve4_graph_init_main_0 }, + { nvf0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvd9_graph_init_pd_0 }, + { nvf0_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nvf0_graph_init_sked_0 }, + { nvf0_graph_init_cwd_0 }, + { nvd9_graph_init_prop_0 }, + { nvc1_graph_init_gpc_unk_0 }, + { nvc0_graph_init_setup_0 }, + { nvc0_graph_init_crstr_0 }, + { nvc1_graph_init_setup_1 }, + { nvc0_graph_init_zcull_0 }, + { nvd9_graph_init_gpm_0 }, + { nvf0_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nve4_graph_init_tpccs_0 }, + { nvf0_graph_init_tex_0 }, + { nve4_graph_init_pe_0 }, + { gk110b_graph_init_l1c_0 }, + { nvc0_graph_init_mpc_0 }, + { gk110b_graph_init_sm_0 }, + { nvd7_graph_init_pes_0 }, + { nvd7_graph_init_wwdx_0 }, + { nvd7_graph_init_cbm_0 }, + { nve4_graph_init_be_0 }, + { nvc0_graph_init_fe_1 }, + {} +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +struct nouveau_oclass * +gk110b_graph_oclass = &(struct nvc0_graph_oclass) { + .base.handle = NV_ENGINE(GR, 0xf1), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_ctor, + .dtor = nvc0_graph_dtor, + .init = nve4_graph_init, + .fini = nvf0_graph_fini, + }, + .cclass = &gk110b_grctx_oclass, + .sclass = nvf0_graph_sclass, + .mmio = gk110b_graph_pack_mmio, + .fecs.ucode = &nvf0_graph_fecs_ucode, + .gpccs.ucode = &nvf0_graph_gpccs_ucode, + .ppc_nr = 2, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c b/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c index 83048a56430d..7d0abe9f3fe7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c @@ -27,8 +27,8 @@ static struct nouveau_oclass gk20a_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0xa040, &nouveau_object_ofuncs }, - { 0xa297, &nouveau_object_ofuncs }, - { 0xa0c0, &nouveau_object_ofuncs }, + { KEPLER_C, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { KEPLER_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; @@ -39,9 +39,10 @@ gk20a_graph_oclass = &(struct nvc0_graph_oclass) { .ctor = nvc0_graph_ctor, .dtor = nvc0_graph_dtor, .init = nve4_graph_init, - .fini = nve4_graph_fini, + .fini = _nouveau_graph_fini, }, .cclass = &gk20a_grctx_oclass, .sclass = gk20a_graph_sclass, .mmio = nve4_graph_pack_mmio, + .ppc_nr = 1, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c b/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c index 21c5f31d607f..4bdbdab2fd9a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c @@ -36,8 +36,8 @@ static struct nouveau_oclass gm107_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0xa140, &nouveau_object_ofuncs }, - { 0xb097, &nouveau_object_ofuncs }, - { 0xb0c0, &nouveau_object_ofuncs }, + { MAXWELL_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { MAXWELL_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; @@ -425,6 +425,9 @@ gm107_graph_init(struct nouveau_object *object) nv_wr32(priv, 0x400134, 0xffffffff); nv_wr32(priv, 0x400054, 0x2c350f63); + + nvc0_graph_zbc_init(priv); + return nvc0_graph_init_ctxctl(priv); } @@ -462,4 +465,5 @@ gm107_graph_oclass = &(struct nvc0_graph_oclass) { .mmio = gm107_graph_pack_mmio, .fecs.ucode = 0 ? &gm107_graph_fecs_ucode : NULL, .gpccs.ucode = &gm107_graph_gpccs_ucode, + .ppc_nr = 2, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c index ad13dcdd15f9..f70e2f67a4dd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c @@ -24,7 +24,6 @@ #include <core/client.h> #include <core/os.h> -#include <core/class.h> #include <core/handle.h> #include <core/namedb.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c index 4532f7e5618c..2b12b09683c8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c @@ -24,7 +24,6 @@ #include <core/client.h> #include <core/os.h> -#include <core/class.h> #include <core/handle.h> #include <subdev/fb.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c index 00ea1a089822..2b0e8f48c029 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c @@ -33,7 +33,7 @@ static struct nouveau_oclass nv108_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0xa140, &nouveau_object_ofuncs }, - { 0xa197, &nouveau_object_ofuncs }, + { KEPLER_B, &nvc0_fermi_ofuncs }, { 0xa1c0, &nouveau_object_ofuncs }, {} }; @@ -220,4 +220,5 @@ nv108_graph_oclass = &(struct nvc0_graph_oclass) { .mmio = nv108_graph_pack_mmio, .fecs.ucode = &nv108_graph_fecs_ucode, .gpccs.ucode = &nv108_graph_gpccs_ucode, + .ppc_nr = 1, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c index d145e080899a..ceb9c746d94e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c @@ -1,6 +1,5 @@ #include <core/client.h> #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/handle.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c index 7a80d005a974..f8a6fdd7d5e8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c @@ -1,5 +1,4 @@ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c index 3e1f32ee43d4..5de9caa2ef67 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c @@ -1,5 +1,4 @@ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c index e451db32e92a..2f9dbc709389 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c @@ -1,5 +1,4 @@ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c index 9385ac7b44a4..34dd26c70b64 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c @@ -1,5 +1,4 @@ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c index 9ce84b73f86a..2fb5756d9f66 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c @@ -1,5 +1,4 @@ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/enum.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 6477fbf6a550..4f401174868d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -24,7 +24,6 @@ #include <core/client.h> #include <core/os.h> -#include <core/class.h> #include <core/handle.h> #include <core/engctx.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index 20665c21d80e..38e0aa26f1cd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/client.h> #include <core/handle.h> #include <core/engctx.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index aa0838916354..db19191176fa 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -26,15 +26,226 @@ #include "ctxnvc0.h" /******************************************************************************* + * Zero Bandwidth Clear + ******************************************************************************/ + +static void +nvc0_graph_zbc_clear_color(struct nvc0_graph_priv *priv, int zbc) +{ + if (priv->zbc_color[zbc].format) { + nv_wr32(priv, 0x405804, priv->zbc_color[zbc].ds[0]); + nv_wr32(priv, 0x405808, priv->zbc_color[zbc].ds[1]); + nv_wr32(priv, 0x40580c, priv->zbc_color[zbc].ds[2]); + nv_wr32(priv, 0x405810, priv->zbc_color[zbc].ds[3]); + } + nv_wr32(priv, 0x405814, priv->zbc_color[zbc].format); + nv_wr32(priv, 0x405820, zbc); + nv_wr32(priv, 0x405824, 0x00000004); /* TRIGGER | WRITE | COLOR */ +} + +static int +nvc0_graph_zbc_color_get(struct nvc0_graph_priv *priv, int format, + const u32 ds[4], const u32 l2[4]) +{ + struct nouveau_ltc *ltc = nouveau_ltc(priv); + int zbc = -ENOSPC, i; + + for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { + if (priv->zbc_color[i].format) { + if (priv->zbc_color[i].format != format) + continue; + if (memcmp(priv->zbc_color[i].ds, ds, sizeof( + priv->zbc_color[i].ds))) + continue; + if (memcmp(priv->zbc_color[i].l2, l2, sizeof( + priv->zbc_color[i].l2))) { + WARN_ON(1); + return -EINVAL; + } + return i; + } else { + zbc = (zbc < 0) ? i : zbc; + } + } + + memcpy(priv->zbc_color[zbc].ds, ds, sizeof(priv->zbc_color[zbc].ds)); + memcpy(priv->zbc_color[zbc].l2, l2, sizeof(priv->zbc_color[zbc].l2)); + priv->zbc_color[zbc].format = format; + ltc->zbc_color_get(ltc, zbc, l2); + nvc0_graph_zbc_clear_color(priv, zbc); + return zbc; +} + +static void +nvc0_graph_zbc_clear_depth(struct nvc0_graph_priv *priv, int zbc) +{ + if (priv->zbc_depth[zbc].format) + nv_wr32(priv, 0x405818, priv->zbc_depth[zbc].ds); + nv_wr32(priv, 0x40581c, priv->zbc_depth[zbc].format); + nv_wr32(priv, 0x405820, zbc); + nv_wr32(priv, 0x405824, 0x00000005); /* TRIGGER | WRITE | DEPTH */ +} + +static int +nvc0_graph_zbc_depth_get(struct nvc0_graph_priv *priv, int format, + const u32 ds, const u32 l2) +{ + struct nouveau_ltc *ltc = nouveau_ltc(priv); + int zbc = -ENOSPC, i; + + for (i = ltc->zbc_min; i <= ltc->zbc_max; i++) { + if (priv->zbc_depth[i].format) { + if (priv->zbc_depth[i].format != format) + continue; + if (priv->zbc_depth[i].ds != ds) + continue; + if (priv->zbc_depth[i].l2 != l2) { + WARN_ON(1); + return -EINVAL; + } + return i; + } else { + zbc = (zbc < 0) ? i : zbc; + } + } + + priv->zbc_depth[zbc].format = format; + priv->zbc_depth[zbc].ds = ds; + priv->zbc_depth[zbc].l2 = l2; + ltc->zbc_depth_get(ltc, zbc, l2); + nvc0_graph_zbc_clear_depth(priv, zbc); + return zbc; +} + +/******************************************************************************* * Graphics object classes ******************************************************************************/ +static int +nvc0_fermi_mthd_zbc_color(struct nouveau_object *object, void *data, u32 size) +{ + struct nvc0_graph_priv *priv = (void *)object->engine; + union { + struct fermi_a_zbc_color_v0 v0; + } *args = data; + int ret; + + if (nvif_unpack(args->v0, 0, 0, false)) { + switch (args->v0.format) { + case FERMI_A_ZBC_COLOR_V0_FMT_ZERO: + case FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE: + case FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32: + case FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16: + case FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16: + case FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16: + case FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16: + case FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16: + case FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8: + case FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8: + case FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10: + case FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10: + case FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8: + case FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8: + case FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8: + case FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8: + case FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8: + case FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10: + case FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11: + ret = nvc0_graph_zbc_color_get(priv, args->v0.format, + args->v0.ds, + args->v0.l2); + if (ret >= 0) { + args->v0.index = ret; + return 0; + } + break; + default: + return -EINVAL; + } + } + + return ret; +} + +static int +nvc0_fermi_mthd_zbc_depth(struct nouveau_object *object, void *data, u32 size) +{ + struct nvc0_graph_priv *priv = (void *)object->engine; + union { + struct fermi_a_zbc_depth_v0 v0; + } *args = data; + int ret; + + if (nvif_unpack(args->v0, 0, 0, false)) { + switch (args->v0.format) { + case FERMI_A_ZBC_DEPTH_V0_FMT_FP32: + ret = nvc0_graph_zbc_depth_get(priv, args->v0.format, + args->v0.ds, + args->v0.l2); + return (ret >= 0) ? 0 : -ENOSPC; + default: + return -EINVAL; + } + } + + return ret; +} + +static int +nvc0_fermi_mthd(struct nouveau_object *object, u32 mthd, void *data, u32 size) +{ + switch (mthd) { + case FERMI_A_ZBC_COLOR: + return nvc0_fermi_mthd_zbc_color(object, data, size); + case FERMI_A_ZBC_DEPTH: + return nvc0_fermi_mthd_zbc_depth(object, data, size); + default: + break; + } + return -EINVAL; +} + +struct nouveau_ofuncs +nvc0_fermi_ofuncs = { + .ctor = _nouveau_object_ctor, + .dtor = nouveau_object_destroy, + .init = nouveau_object_init, + .fini = nouveau_object_fini, + .mthd = nvc0_fermi_mthd, +}; + +static int +nvc0_graph_set_shader_exceptions(struct nouveau_object *object, u32 mthd, + void *pdata, u32 size) +{ + struct nvc0_graph_priv *priv = (void *)nv_engine(object); + if (size >= sizeof(u32)) { + u32 data = *(u32 *)pdata ? 0xffffffff : 0x00000000; + nv_wr32(priv, 0x419e44, data); + nv_wr32(priv, 0x419e4c, data); + return 0; + } + return -EINVAL; +} + +struct nouveau_omthds +nvc0_graph_9097_omthds[] = { + { 0x1528, 0x1528, nvc0_graph_set_shader_exceptions }, + {} +}; + +struct nouveau_omthds +nvc0_graph_90c0_omthds[] = { + { 0x1528, 0x1528, nvc0_graph_set_shader_exceptions }, + {} +}; + struct nouveau_oclass nvc0_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0x9039, &nouveau_object_ofuncs }, - { 0x9097, &nouveau_object_ofuncs }, - { 0x90c0, &nouveau_object_ofuncs }, + { FERMI_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { FERMI_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; @@ -98,7 +309,7 @@ nvc0_graph_context_ctor(struct nouveau_object *parent, u32 addr = mmio->addr; u32 data = mmio->data; - if (mmio->shift) { + if (mmio->buffer >= 0) { u64 info = chan->data[mmio->buffer].vma.offset; data |= info >> mmio->shift; } @@ -407,6 +618,35 @@ nvc0_graph_pack_mmio[] = { ******************************************************************************/ void +nvc0_graph_zbc_init(struct nvc0_graph_priv *priv) +{ + const u32 zero[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + const u32 one[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + const u32 f32_0[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + const u32 f32_1[] = { 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, + 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000 }; + struct nouveau_ltc *ltc = nouveau_ltc(priv); + int index; + + if (!priv->zbc_color[0].format) { + nvc0_graph_zbc_color_get(priv, 1, & zero[0], &zero[4]); + nvc0_graph_zbc_color_get(priv, 2, & one[0], &one[4]); + nvc0_graph_zbc_color_get(priv, 4, &f32_0[0], &f32_0[4]); + nvc0_graph_zbc_color_get(priv, 4, &f32_1[0], &f32_1[4]); + nvc0_graph_zbc_depth_get(priv, 1, 0x00000000, 0x00000000); + nvc0_graph_zbc_depth_get(priv, 1, 0x3f800000, 0x3f800000); + } + + for (index = ltc->zbc_min; index <= ltc->zbc_max; index++) + nvc0_graph_zbc_clear_color(priv, index); + for (index = ltc->zbc_min; index <= ltc->zbc_max; index++) + nvc0_graph_zbc_clear_depth(priv, index); +} + +void nvc0_graph_mmio(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p) { const struct nvc0_graph_pack *pack; @@ -969,17 +1209,16 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv) { struct nvc0_graph_oclass *oclass = (void *)nv_object(priv)->oclass; struct nvc0_grctx_oclass *cclass = (void *)nv_engine(priv)->cclass; - u32 r000260; int i; if (priv->firmware) { /* load fuc microcode */ - r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 0); nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d); nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad); - nv_wr32(priv, 0x000260, r000260); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 1); /* start both of them running */ nv_wr32(priv, 0x409840, 0xffffffff); @@ -1066,7 +1305,7 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv) } /* load HUB microcode */ - r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 0); nv_wr32(priv, 0x4091c0, 0x01000000); for (i = 0; i < oclass->fecs.ucode->data.size / 4; i++) nv_wr32(priv, 0x4091c4, oclass->fecs.ucode->data.data[i]); @@ -1089,7 +1328,7 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x41a188, i >> 6); nv_wr32(priv, 0x41a184, oclass->gpccs.ucode->code.data[i]); } - nv_wr32(priv, 0x000260, r000260); + nouveau_mc(priv)->unk260(nouveau_mc(priv), 1); /* load register lists */ nvc0_graph_init_csdata(priv, cclass->hub, 0x409000, 0x000, 0x000000); @@ -1224,6 +1463,9 @@ nvc0_graph_init(struct nouveau_object *object) nv_wr32(priv, 0x400134, 0xffffffff); nv_wr32(priv, 0x400054, 0x34ce3464); + + nvc0_graph_zbc_init(priv); + return nvc0_graph_init_ctxctl(priv); } @@ -1287,7 +1529,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_device *device = nv_device(parent); struct nvc0_graph_priv *priv; bool use_ext_fw, enable; - int ret, i; + int ret, i, j; use_ext_fw = nouveau_boolopt(device->cfgopt, "NvGrUseFW", oclass->fecs.ucode == NULL); @@ -1333,6 +1575,11 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, for (i = 0; i < priv->gpc_nr; i++) { priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608)); priv->tpc_total += priv->tpc_nr[i]; + priv->ppc_nr[i] = oclass->ppc_nr; + for (j = 0; j < priv->ppc_nr[i]; j++) { + u8 mask = nv_rd32(priv, GPC_UNIT(i, 0x0c30 + (j * 4))); + priv->ppc_tpc_nr[i][j] = hweight8(mask); + } } /*XXX: these need figuring out... though it might not even matter */ diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h index ffc289198dd8..7ed9e89c3435 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h @@ -30,10 +30,15 @@ #include <core/gpuobj.h> #include <core/option.h> +#include <nvif/unpack.h> +#include <nvif/class.h> + #include <subdev/fb.h> #include <subdev/vm.h> #include <subdev/bar.h> #include <subdev/timer.h> +#include <subdev/mc.h> +#include <subdev/ltc.h> #include <engine/fifo.h> #include <engine/graph.h> @@ -60,7 +65,7 @@ struct nvc0_graph_mmio { u32 addr; u32 data; u32 shift; - u32 buffer; + int buffer; }; struct nvc0_graph_fuc { @@ -68,6 +73,18 @@ struct nvc0_graph_fuc { u32 size; }; +struct nvc0_graph_zbc_color { + u32 format; + u32 ds[4]; + u32 l2[4]; +}; + +struct nvc0_graph_zbc_depth { + u32 format; + u32 ds; + u32 l2; +}; + struct nvc0_graph_priv { struct nouveau_graph base; @@ -77,10 +94,15 @@ struct nvc0_graph_priv { struct nvc0_graph_fuc fuc41ad; bool firmware; + struct nvc0_graph_zbc_color zbc_color[NOUVEAU_LTC_MAX_ZBC_CNT]; + struct nvc0_graph_zbc_depth zbc_depth[NOUVEAU_LTC_MAX_ZBC_CNT]; + u8 rop_nr; u8 gpc_nr; u8 tpc_nr[GPC_MAX]; u8 tpc_total; + u8 ppc_nr[GPC_MAX]; + u8 ppc_tpc_nr[GPC_MAX][4]; struct nouveau_gpuobj *unk4188b4; struct nouveau_gpuobj *unk4188b8; @@ -118,12 +140,20 @@ int nvc0_graph_ctor(struct nouveau_object *, struct nouveau_object *, struct nouveau_object **); void nvc0_graph_dtor(struct nouveau_object *); int nvc0_graph_init(struct nouveau_object *); +void nvc0_graph_zbc_init(struct nvc0_graph_priv *); + int nve4_graph_fini(struct nouveau_object *, bool); int nve4_graph_init(struct nouveau_object *); -extern struct nouveau_oclass nvc0_graph_sclass[]; +int nvf0_graph_fini(struct nouveau_object *, bool); + +extern struct nouveau_ofuncs nvc0_fermi_ofuncs; +extern struct nouveau_oclass nvc0_graph_sclass[]; +extern struct nouveau_omthds nvc0_graph_9097_omthds[]; +extern struct nouveau_omthds nvc0_graph_90c0_omthds[]; extern struct nouveau_oclass nvc8_graph_sclass[]; +extern struct nouveau_oclass nvf0_graph_sclass[]; struct nvc0_graph_init { u32 addr; @@ -149,6 +179,9 @@ struct nvc0_graph_ucode { extern struct nvc0_graph_ucode nvc0_graph_fecs_ucode; extern struct nvc0_graph_ucode nvc0_graph_gpccs_ucode; +extern struct nvc0_graph_ucode nvf0_graph_fecs_ucode; +extern struct nvc0_graph_ucode nvf0_graph_gpccs_ucode; + struct nvc0_graph_oclass { struct nouveau_oclass base; struct nouveau_oclass **cclass; @@ -160,6 +193,7 @@ struct nvc0_graph_oclass { struct { struct nvc0_graph_ucode *ucode; } gpccs; + int ppc_nr; }; void nvc0_graph_mmio(struct nvc0_graph_priv *, const struct nvc0_graph_pack *); @@ -223,9 +257,11 @@ extern const struct nvc0_graph_init nve4_graph_init_be_0[]; extern const struct nvc0_graph_pack nve4_graph_pack_mmio[]; extern const struct nvc0_graph_init nvf0_graph_init_fe_0[]; +extern const struct nvc0_graph_init nvf0_graph_init_ds_0[]; extern const struct nvc0_graph_init nvf0_graph_init_sked_0[]; extern const struct nvc0_graph_init nvf0_graph_init_cwd_0[]; extern const struct nvc0_graph_init nvf0_graph_init_gpc_unk_1[]; +extern const struct nvc0_graph_init nvf0_graph_init_tex_0[]; extern const struct nvc0_graph_init nvf0_graph_init_sm_0[]; extern const struct nvc0_graph_init nv108_graph_init_gpc_unk_0[]; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c index 30cab0b2eba1..93d58e5b82c2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c @@ -33,9 +33,9 @@ static struct nouveau_oclass nvc1_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0x9039, &nouveau_object_ofuncs }, - { 0x9097, &nouveau_object_ofuncs }, - { 0x90c0, &nouveau_object_ofuncs }, - { 0x9197, &nouveau_object_ofuncs }, + { FERMI_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { FERMI_B, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { FERMI_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c index a6bf783e1256..692e1eda0eb4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c @@ -33,10 +33,10 @@ struct nouveau_oclass nvc8_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0x9039, &nouveau_object_ofuncs }, - { 0x9097, &nouveau_object_ofuncs }, - { 0x90c0, &nouveau_object_ofuncs }, - { 0x9197, &nouveau_object_ofuncs }, - { 0x9297, &nouveau_object_ofuncs }, + { FERMI_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { FERMI_B, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { FERMI_C, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { FERMI_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c index 2a6a94e2a041..41e8445c7eea 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c @@ -133,4 +133,5 @@ nvd7_graph_oclass = &(struct nvc0_graph_oclass) { .mmio = nvd7_graph_pack_mmio, .fecs.ucode = &nvd7_graph_fecs_ucode, .gpccs.ucode = &nvd7_graph_gpccs_ucode, + .ppc_nr = 1, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c index 51e0c075ad34..0c71f5c67ae0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c @@ -22,6 +22,8 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ +#include <subdev/pwr.h> + #include "nvc0.h" #include "ctxnvc0.h" @@ -33,8 +35,8 @@ static struct nouveau_oclass nve4_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0xa040, &nouveau_object_ofuncs }, - { 0xa097, &nouveau_object_ofuncs }, - { 0xa0c0, &nouveau_object_ofuncs }, + { KEPLER_A, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { KEPLER_COMPUTE_A, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; @@ -190,39 +192,20 @@ nve4_graph_pack_mmio[] = { ******************************************************************************/ int -nve4_graph_fini(struct nouveau_object *object, bool suspend) -{ - struct nvc0_graph_priv *priv = (void *)object; - - /*XXX: this is a nasty hack to power on gr on certain boards - * where it's disabled by therm, somehow. ideally it'd - * be nice to know when we should be doing this, and why, - * but, it's yet to be determined. for now we test for - * the particular mmio error that occurs in the situation, - * and then bash therm in the way nvidia do. - */ - nv_mask(priv, 0x000200, 0x08001000, 0x08001000); - nv_rd32(priv, 0x000200); - if (nv_rd32(priv, 0x400700) == 0xbadf1000) { - nv_mask(priv, 0x000200, 0x08001000, 0x00000000); - nv_rd32(priv, 0x000200); - nv_mask(priv, 0x020004, 0xc0000000, 0x40000000); - } - - return nouveau_graph_fini(&priv->base, suspend); -} - -int nve4_graph_init(struct nouveau_object *object) { struct nvc0_graph_oclass *oclass = (void *)object->oclass; struct nvc0_graph_priv *priv = (void *)object; + struct nouveau_pwr *ppwr = nouveau_pwr(priv); const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total); u32 data[TPC_MAX / 8] = {}; u8 tpcnr[GPC_MAX]; int gpc, tpc, rop; int ret, i; + if (ppwr) + ppwr->pgob(ppwr, false); + ret = nouveau_graph_init(&priv->base); if (ret) return ret; @@ -320,6 +303,9 @@ nve4_graph_init(struct nouveau_object *object) nv_wr32(priv, 0x400134, 0xffffffff); nv_wr32(priv, 0x400054, 0x34ce3464); + + nvc0_graph_zbc_init(priv); + return nvc0_graph_init_ctxctl(priv); } @@ -350,11 +336,12 @@ nve4_graph_oclass = &(struct nvc0_graph_oclass) { .ctor = nvc0_graph_ctor, .dtor = nvc0_graph_dtor, .init = nve4_graph_init, - .fini = nve4_graph_fini, + .fini = _nouveau_graph_fini, }, .cclass = &nve4_grctx_oclass, .sclass = nve4_graph_sclass, .mmio = nve4_graph_pack_mmio, .fecs.ucode = &nve4_graph_fecs_ucode, .gpccs.ucode = &nve4_graph_gpccs_ucode, + .ppc_nr = 1, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c index c96762122b9b..c306c0f2fc84 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c @@ -29,12 +29,12 @@ * Graphics object classes ******************************************************************************/ -static struct nouveau_oclass +struct nouveau_oclass nvf0_graph_sclass[] = { { 0x902d, &nouveau_object_ofuncs }, { 0xa140, &nouveau_object_ofuncs }, - { 0xa197, &nouveau_object_ofuncs }, - { 0xa1c0, &nouveau_object_ofuncs }, + { KEPLER_B, &nvc0_fermi_ofuncs, nvc0_graph_9097_omthds }, + { KEPLER_COMPUTE_B, &nouveau_object_ofuncs, nvc0_graph_90c0_omthds }, {} }; @@ -50,7 +50,7 @@ nvf0_graph_init_fe_0[] = { {} }; -static const struct nvc0_graph_init +const struct nvc0_graph_init nvf0_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, @@ -88,7 +88,7 @@ nvf0_graph_init_gpc_unk_1[] = { {} }; -static const struct nvc0_graph_init +const struct nvc0_graph_init nvf0_graph_init_tex_0[] = { { 0x419ab0, 1, 0x04, 0x00000000 }, { 0x419ac8, 1, 0x04, 0x00000000 }, @@ -170,7 +170,7 @@ nvf0_graph_pack_mmio[] = { * PGRAPH engine/subdev functions ******************************************************************************/ -static int +int nvf0_graph_fini(struct nouveau_object *object, bool suspend) { struct nvc0_graph_priv *priv = (void *)object; @@ -209,7 +209,7 @@ nvf0_graph_fini(struct nouveau_object *object, bool suspend) #include "fuc/hubnvf0.fuc.h" -static struct nvc0_graph_ucode +struct nvc0_graph_ucode nvf0_graph_fecs_ucode = { .code.data = nvf0_grhub_code, .code.size = sizeof(nvf0_grhub_code), @@ -219,7 +219,7 @@ nvf0_graph_fecs_ucode = { #include "fuc/gpcnvf0.fuc.h" -static struct nvc0_graph_ucode +struct nvc0_graph_ucode nvf0_graph_gpccs_ucode = { .code.data = nvf0_grgpc_code, .code.size = sizeof(nvf0_grgpc_code), @@ -241,4 +241,5 @@ nvf0_graph_oclass = &(struct nvc0_graph_oclass) { .mmio = nvf0_graph_pack_mmio, .fecs.ucode = &nvf0_graph_fecs_ucode, .gpccs.ucode = &nvf0_graph_gpccs_ucode, + .ppc_nr = 2, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c index 7eb6d94c84e2..d88c700b2f69 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c @@ -24,7 +24,6 @@ #include <core/client.h> #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/handle.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index d4e7ec0ba68c..bdb2f20ff7b1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <subdev/fb.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c index 3d8c2133e0e8..72c7f33fd29b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/client.h> #include <core/engctx.h> #include <core/handle.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c index 37a2bd9e8078..cae33f86b11a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv50.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <subdev/vm.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c index 96f5aa92677b..e9cc8b116a24 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv84.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <subdev/vm.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c index e9c5e51943ef..63013812f7c9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c @@ -22,8 +22,11 @@ * Authors: Ben Skeggs */ +#include <core/client.h> #include <core/option.h> -#include <core/class.h> +#include <nvif/unpack.h> +#include <nvif/class.h> +#include <nvif/ioctl.h> #include <subdev/clock.h> @@ -101,24 +104,28 @@ nouveau_perfsig_wrap(struct nouveau_perfmon *ppm, const char *name, * Perfmon object classes ******************************************************************************/ static int -nouveau_perfctr_query(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nouveau_perfctr_query(struct nouveau_object *object, void *data, u32 size) { + union { + struct nvif_perfctr_query_v0 v0; + } *args = data; struct nouveau_device *device = nv_device(object); struct nouveau_perfmon *ppm = (void *)object->engine; struct nouveau_perfdom *dom = NULL, *chk; - struct nv_perfctr_query *args = data; const bool all = nouveau_boolopt(device->cfgopt, "NvPmShowAll", false); const bool raw = nouveau_boolopt(device->cfgopt, "NvPmUnnamed", all); const char *name; int tmp = 0, di, si; - char path[64]; - - if (size < sizeof(*args)) - return -EINVAL; + int ret; - di = (args->iter & 0xff000000) >> 24; - si = (args->iter & 0x00ffffff) - 1; + nv_ioctl(object, "perfctr query size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "perfctr query vers %d iter %08x\n", + args->v0.version, args->v0.iter); + di = (args->v0.iter & 0xff000000) >> 24; + si = (args->v0.iter & 0x00ffffff) - 1; + } else + return ret; list_for_each_entry(chk, &ppm->domains, head) { if (tmp++ == di) { @@ -132,19 +139,17 @@ nouveau_perfctr_query(struct nouveau_object *object, u32 mthd, if (si >= 0) { if (raw || !(name = dom->signal[si].name)) { - snprintf(path, sizeof(path), "/%s/%02x", dom->name, si); - name = path; + snprintf(args->v0.name, sizeof(args->v0.name), + "/%s/%02x", dom->name, si); + } else { + strncpy(args->v0.name, name, sizeof(args->v0.name)); } - - if (args->name) - strncpy(args->name, name, args->size); - args->size = strlen(name) + 1; } do { while (++si < dom->signal_nr) { if (all || dom->signal[si].name) { - args->iter = (di << 24) | ++si; + args->v0.iter = (di << 24) | ++si; return 0; } } @@ -153,21 +158,26 @@ nouveau_perfctr_query(struct nouveau_object *object, u32 mthd, dom = list_entry(dom->head.next, typeof(*dom), head); } while (&dom->head != &ppm->domains); - args->iter = 0xffffffff; + args->v0.iter = 0xffffffff; return 0; } static int -nouveau_perfctr_sample(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nouveau_perfctr_sample(struct nouveau_object *object, void *data, u32 size) { + union { + struct nvif_perfctr_sample none; + } *args = data; struct nouveau_perfmon *ppm = (void *)object->engine; struct nouveau_perfctr *ctr, *tmp; struct nouveau_perfdom *dom; - struct nv_perfctr_sample *args = data; + int ret; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(object, "perfctr sample size %d\n", size); + if (nvif_unvers(args->none)) { + nv_ioctl(object, "perfctr sample\n"); + } else + return ret; ppm->sequence++; list_for_each_entry(dom, &ppm->domains, head) { @@ -206,22 +216,45 @@ nouveau_perfctr_sample(struct nouveau_object *object, u32 mthd, } static int -nouveau_perfctr_read(struct nouveau_object *object, u32 mthd, - void *data, u32 size) +nouveau_perfctr_read(struct nouveau_object *object, void *data, u32 size) { + union { + struct nvif_perfctr_read_v0 v0; + } *args = data; struct nouveau_perfctr *ctr = (void *)object; - struct nv_perfctr_read *args = data; + int ret; + + nv_ioctl(object, "perfctr read size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(object, "perfctr read vers %d\n", args->v0.version); + } else + return ret; - if (size < sizeof(*args)) - return -EINVAL; if (!ctr->clk) return -EAGAIN; - args->clk = ctr->clk; - args->ctr = ctr->ctr; + args->v0.clk = ctr->clk; + args->v0.ctr = ctr->ctr; return 0; } +static int +nouveau_perfctr_mthd(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + switch (mthd) { + case NVIF_PERFCTR_V0_QUERY: + return nouveau_perfctr_query(object, data, size); + case NVIF_PERFCTR_V0_SAMPLE: + return nouveau_perfctr_sample(object, data, size); + case NVIF_PERFCTR_V0_READ: + return nouveau_perfctr_read(object, data, size); + default: + break; + } + return -EINVAL; +} + static void nouveau_perfctr_dtor(struct nouveau_object *object) { @@ -237,19 +270,27 @@ nouveau_perfctr_ctor(struct nouveau_object *parent, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + union { + struct nvif_perfctr_v0 v0; + } *args = data; struct nouveau_perfmon *ppm = (void *)engine; struct nouveau_perfdom *dom = NULL; struct nouveau_perfsig *sig[4] = {}; struct nouveau_perfctr *ctr; - struct nv_perfctr_class *args = data; int ret, i; - if (size < sizeof(*args)) - return -EINVAL; + nv_ioctl(parent, "create perfctr size %d\n", size); + if (nvif_unpack(args->v0, 0, 0, false)) { + nv_ioctl(parent, "create perfctr vers %d logic_op %04x\n", + args->v0.version, args->v0.logic_op); + } else + return ret; - for (i = 0; i < ARRAY_SIZE(args->signal) && args->signal[i].name; i++) { - sig[i] = nouveau_perfsig_find(ppm, args->signal[i].name, - args->signal[i].size, &dom); + for (i = 0; i < ARRAY_SIZE(args->v0.name) && args->v0.name[i][0]; i++) { + sig[i] = nouveau_perfsig_find(ppm, args->v0.name[i], + strnlen(args->v0.name[i], + sizeof(args->v0.name[i])), + &dom); if (!sig[i]) return -EINVAL; } @@ -260,7 +301,7 @@ nouveau_perfctr_ctor(struct nouveau_object *parent, return ret; ctr->slot = -1; - ctr->logic_op = args->logic_op; + ctr->logic_op = args->v0.logic_op; ctr->signal[0] = sig[0]; ctr->signal[1] = sig[1]; ctr->signal[2] = sig[2]; @@ -276,21 +317,13 @@ nouveau_perfctr_ofuncs = { .dtor = nouveau_perfctr_dtor, .init = nouveau_object_init, .fini = nouveau_object_fini, -}; - -static struct nouveau_omthds -nouveau_perfctr_omthds[] = { - { NV_PERFCTR_QUERY, NV_PERFCTR_QUERY, nouveau_perfctr_query }, - { NV_PERFCTR_SAMPLE, NV_PERFCTR_SAMPLE, nouveau_perfctr_sample }, - { NV_PERFCTR_READ, NV_PERFCTR_READ, nouveau_perfctr_read }, - {} + .mthd = nouveau_perfctr_mthd, }; struct nouveau_oclass nouveau_perfmon_sclass[] = { - { .handle = NV_PERFCTR_CLASS, + { .handle = NVIF_IOCTL_NEW_V0_PERFCTR, .ofuncs = &nouveau_perfctr_ofuncs, - .omthds = nouveau_perfctr_omthds, }, {}, }; @@ -303,6 +336,7 @@ nouveau_perfctx_dtor(struct nouveau_object *object) { struct nouveau_perfmon *ppm = (void *)object->engine; mutex_lock(&nv_subdev(ppm)->mutex); + nouveau_engctx_destroy(&ppm->context->base); ppm->context = NULL; mutex_unlock(&nv_subdev(ppm)->mutex); } diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c index c571758e4a27..64df15c7f051 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <engine/software.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c index a62f11a78430..f54a2253deca 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <engine/software.h> diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c index f3b4d9dbf23c..4d2994d8cc32 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c @@ -23,12 +23,12 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/namedb.h> #include <core/handle.h> #include <core/gpuobj.h> #include <core/event.h> +#include <nvif/event.h> #include <subdev/bar.h> @@ -86,10 +86,10 @@ nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); u32 head = *(u32 *)args; - if (head >= chan->vblank.nr_event) + if (head >= nouveau_disp(chan)->vblank.index_nr) return -EINVAL; - nouveau_event_get(chan->vblank.event[head]); + nvkm_notify_get(&chan->vblank.notify[head]); return 0; } @@ -124,9 +124,10 @@ nv50_software_sclass[] = { ******************************************************************************/ static int -nv50_software_vblsem_release(void *data, u32 type, int head) +nv50_software_vblsem_release(struct nvkm_notify *notify) { - struct nv50_software_chan *chan = data; + struct nv50_software_chan *chan = + container_of(notify, typeof(*chan), vblank.notify[notify->index]); struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); @@ -142,7 +143,7 @@ nv50_software_vblsem_release(void *data, u32 type, int head) nv_wr32(priv, 0x060014, chan->vblank.value); } - return NVKM_EVENT_DROP; + return NVKM_NOTIFY_DROP; } void @@ -151,11 +152,8 @@ nv50_software_context_dtor(struct nouveau_object *object) struct nv50_software_chan *chan = (void *)object; int i; - if (chan->vblank.event) { - for (i = 0; i < chan->vblank.nr_event; i++) - nouveau_event_ref(NULL, &chan->vblank.event[i]); - kfree(chan->vblank.event); - } + for (i = 0; i < ARRAY_SIZE(chan->vblank.notify); i++) + nvkm_notify_fini(&chan->vblank.notify[i]); nouveau_software_context_destroy(&chan->base); } @@ -176,15 +174,14 @@ nv50_software_context_ctor(struct nouveau_object *parent, if (ret) return ret; - chan->vblank.nr_event = pdisp ? pdisp->vblank->index_nr : 0; - chan->vblank.event = kzalloc(chan->vblank.nr_event * - sizeof(*chan->vblank.event), GFP_KERNEL); - if (!chan->vblank.event) - return -ENOMEM; - - for (i = 0; i < chan->vblank.nr_event; i++) { - ret = nouveau_event_new(pdisp->vblank, 1, i, pclass->vblank, - chan, &chan->vblank.event[i]); + for (i = 0; pdisp && i < pdisp->vblank.index_nr; i++) { + ret = nvkm_notify_init(&pdisp->vblank, pclass->vblank, false, + &(struct nvif_notify_head_req_v0) { + .head = i, + }, + sizeof(struct nvif_notify_head_req_v0), + sizeof(struct nvif_notify_head_rep_v0), + &chan->vblank.notify[i]); if (ret) return ret; } @@ -198,7 +195,7 @@ nv50_software_cclass = { .base.handle = NV_ENGCTX(SW, 0x50), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_software_context_ctor, - .dtor = _nouveau_software_context_dtor, + .dtor = nv50_software_context_dtor, .init = _nouveau_software_context_init, .fini = _nouveau_software_context_fini, }, diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h index bb49a7a20857..41542e725b4b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h @@ -19,14 +19,13 @@ int nv50_software_ctor(struct nouveau_object *, struct nouveau_object *, struct nv50_software_cclass { struct nouveau_oclass base; - int (*vblank)(void *, u32, int); + int (*vblank)(struct nvkm_notify *); }; struct nv50_software_chan { struct nouveau_software_chan base; struct { - struct nouveau_eventh **event; - int nr_event; + struct nvkm_notify notify[4]; u32 channel; u32 ctxdma; u64 offset; diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c index 135c20f38356..6af370d3a06d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c @@ -23,7 +23,6 @@ */ #include <core/os.h> -#include <core/class.h> #include <core/engctx.h> #include <core/event.h> @@ -104,9 +103,10 @@ nvc0_software_sclass[] = { ******************************************************************************/ static int -nvc0_software_vblsem_release(void *data, u32 type, int head) +nvc0_software_vblsem_release(struct nvkm_notify *notify) { - struct nv50_software_chan *chan = data; + struct nv50_software_chan *chan = + container_of(notify, typeof(*chan), vblank.notify[notify->index]); struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); @@ -116,7 +116,7 @@ nvc0_software_vblsem_release(void *data, u32 type, int head) nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060014, chan->vblank.value); - return NVKM_EVENT_DROP; + return NVKM_NOTIFY_DROP; } static struct nv50_software_cclass @@ -124,7 +124,7 @@ nvc0_software_cclass = { .base.handle = NV_ENGCTX(SW, 0xc0), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_software_context_ctor, - .dtor = _nouveau_software_context_dtor, + .dtor = nv50_software_context_dtor, .init = _nouveau_software_context_init, .fini = _nouveau_software_context_fini, }, |