diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau')
257 files changed, 15088 insertions, 6600 deletions
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 7cf787d697b..637c29a3312 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -11,7 +11,7 @@ config DRM_NOUVEAU select FB select FRAMEBUFFER_CONSOLE if !EXPERT select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT - select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT + select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT select X86_PLATFORM_DEVICES if ACPI && X86 select ACPI_WMI if ACPI && X86 select MXM_WMI if ACPI && X86 @@ -19,7 +19,6 @@ config DRM_NOUVEAU # Similar to i915, we need to select ACPI_VIDEO and it's dependencies select BACKLIGHT_LCD_SUPPORT if ACPI && X86 select BACKLIGHT_CLASS_DEVICE if ACPI && X86 - select VIDEO_OUTPUT_CONTROL if ACPI && X86 select INPUT if ACPI && X86 select THERMAL if ACPI && X86 select ACPI_VIDEO if ACPI && X86 diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e88145ba1bf..8b307e14363 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -48,6 +48,7 @@ nouveau-y += core/subdev/bios/therm.o nouveau-y += core/subdev/bios/vmap.o nouveau-y += core/subdev/bios/volt.o nouveau-y += core/subdev/bios/xpio.o +nouveau-y += core/subdev/bios/P0260.o nouveau-y += core/subdev/bus/hwsq.o nouveau-y += core/subdev/bus/nv04.o nouveau-y += core/subdev/bus/nv31.o @@ -77,6 +78,7 @@ nouveau-y += core/subdev/devinit/nv98.o nouveau-y += core/subdev/devinit/nva3.o nouveau-y += core/subdev/devinit/nvaf.o nouveau-y += core/subdev/devinit/nvc0.o +nouveau-y += core/subdev/devinit/gm107.o nouveau-y += core/subdev/fb/base.o nouveau-y += core/subdev/fb/nv04.o nouveau-y += core/subdev/fb/nv10.o @@ -100,6 +102,8 @@ nouveau-y += core/subdev/fb/nvaa.o nouveau-y += core/subdev/fb/nvaf.o nouveau-y += core/subdev/fb/nvc0.o nouveau-y += core/subdev/fb/nve0.o +nouveau-y += core/subdev/fb/gk20a.o +nouveau-y += core/subdev/fb/gm107.o nouveau-y += core/subdev/fb/ramnv04.o nouveau-y += core/subdev/fb/ramnv10.o nouveau-y += core/subdev/fb/ramnv1a.o @@ -114,33 +118,44 @@ nouveau-y += core/subdev/fb/ramnva3.o nouveau-y += core/subdev/fb/ramnvaa.o nouveau-y += core/subdev/fb/ramnvc0.o nouveau-y += core/subdev/fb/ramnve0.o +nouveau-y += core/subdev/fb/ramgk20a.o +nouveau-y += core/subdev/fb/ramgm107.o nouveau-y += core/subdev/fb/sddr3.o nouveau-y += core/subdev/fb/gddr5.o nouveau-y += core/subdev/gpio/base.o nouveau-y += core/subdev/gpio/nv10.o nouveau-y += core/subdev/gpio/nv50.o +nouveau-y += core/subdev/gpio/nv92.o nouveau-y += core/subdev/gpio/nvd0.o nouveau-y += core/subdev/gpio/nve0.o nouveau-y += core/subdev/i2c/base.o nouveau-y += core/subdev/i2c/anx9805.o nouveau-y += core/subdev/i2c/aux.o nouveau-y += core/subdev/i2c/bit.o +nouveau-y += core/subdev/i2c/pad.o +nouveau-y += core/subdev/i2c/padnv04.o +nouveau-y += core/subdev/i2c/padnv94.o nouveau-y += core/subdev/i2c/nv04.o nouveau-y += core/subdev/i2c/nv4e.o nouveau-y += core/subdev/i2c/nv50.o nouveau-y += core/subdev/i2c/nv94.o nouveau-y += core/subdev/i2c/nvd0.o +nouveau-y += core/subdev/i2c/gf117.o +nouveau-y += core/subdev/i2c/nve0.o nouveau-y += core/subdev/ibus/nvc0.o nouveau-y += core/subdev/ibus/nve0.o +nouveau-y += core/subdev/ibus/gk20a.o nouveau-y += core/subdev/instmem/base.o nouveau-y += core/subdev/instmem/nv04.o nouveau-y += core/subdev/instmem/nv40.o nouveau-y += core/subdev/instmem/nv50.o -nouveau-y += core/subdev/ltcg/nvc0.o +nouveau-y += core/subdev/ltcg/gf100.o +nouveau-y += core/subdev/ltcg/gm107.o nouveau-y += core/subdev/mc/base.o nouveau-y += core/subdev/mc/nv04.o nouveau-y += core/subdev/mc/nv40.o nouveau-y += core/subdev/mc/nv44.o +nouveau-y += core/subdev/mc/nv4c.o nouveau-y += core/subdev/mc/nv50.o nouveau-y += core/subdev/mc/nv94.o nouveau-y += core/subdev/mc/nv98.o @@ -169,6 +184,7 @@ nouveau-y += core/subdev/therm/nva3.o nouveau-y += core/subdev/therm/nvd0.o nouveau-y += core/subdev/timer/base.o nouveau-y += core/subdev/timer/nv04.o +nouveau-y += core/subdev/timer/gk20a.o nouveau-y += core/subdev/vm/base.o nouveau-y += core/subdev/vm/nv04.o nouveau-y += core/subdev/vm/nv41.o @@ -205,7 +221,11 @@ nouveau-y += core/engine/device/nv40.o nouveau-y += core/engine/device/nv50.o nouveau-y += core/engine/device/nvc0.o nouveau-y += core/engine/device/nve0.o +nouveau-y += core/engine/device/gm100.o nouveau-y += core/engine/disp/base.o +nouveau-y += core/engine/disp/conn.o +nouveau-y += core/engine/disp/outp.o +nouveau-y += core/engine/disp/outpdp.o nouveau-y += core/engine/disp/nv04.o nouveau-y += core/engine/disp/nv50.o nouveau-y += core/engine/disp/nv84.o @@ -215,6 +235,7 @@ nouveau-y += core/engine/disp/nva3.o nouveau-y += core/engine/disp/nvd0.o nouveau-y += core/engine/disp/nve0.o nouveau-y += core/engine/disp/nvf0.o +nouveau-y += core/engine/disp/gm107.o nouveau-y += core/engine/disp/dacnv50.o nouveau-y += core/engine/disp/dport.o nouveau-y += core/engine/disp/hdanva3.o @@ -236,18 +257,21 @@ nouveau-y += core/engine/fifo/nv50.o nouveau-y += core/engine/fifo/nv84.o nouveau-y += core/engine/fifo/nvc0.o nouveau-y += core/engine/fifo/nve0.o +nouveau-y += core/engine/fifo/gk20a.o nouveau-y += core/engine/fifo/nv108.o nouveau-y += core/engine/graph/ctxnv40.o nouveau-y += core/engine/graph/ctxnv50.o nouveau-y += core/engine/graph/ctxnvc0.o nouveau-y += core/engine/graph/ctxnvc1.o -nouveau-y += core/engine/graph/ctxnvc3.o +nouveau-y += core/engine/graph/ctxnvc4.o nouveau-y += core/engine/graph/ctxnvc8.o nouveau-y += core/engine/graph/ctxnvd7.o nouveau-y += core/engine/graph/ctxnvd9.o nouveau-y += core/engine/graph/ctxnve4.o +nouveau-y += core/engine/graph/ctxgk20a.o nouveau-y += core/engine/graph/ctxnvf0.o nouveau-y += core/engine/graph/ctxnv108.o +nouveau-y += core/engine/graph/ctxgm107.o nouveau-y += core/engine/graph/nv04.o nouveau-y += core/engine/graph/nv10.o nouveau-y += core/engine/graph/nv20.o @@ -260,13 +284,15 @@ nouveau-y += core/engine/graph/nv40.o nouveau-y += core/engine/graph/nv50.o nouveau-y += core/engine/graph/nvc0.o nouveau-y += core/engine/graph/nvc1.o -nouveau-y += core/engine/graph/nvc3.o +nouveau-y += core/engine/graph/nvc4.o nouveau-y += core/engine/graph/nvc8.o nouveau-y += core/engine/graph/nvd7.o nouveau-y += core/engine/graph/nvd9.o nouveau-y += core/engine/graph/nve4.o +nouveau-y += core/engine/graph/gk20a.o nouveau-y += core/engine/graph/nvf0.o nouveau-y += core/engine/graph/nv108.o +nouveau-y += core/engine/graph/gm107.o nouveau-y += core/engine/mpeg/nv31.o nouveau-y += core/engine/mpeg/nv40.o nouveau-y += core/engine/mpeg/nv44.o diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index 3f3c76581a9..ae81d3b5d8b 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c @@ -28,14 +28,20 @@ nouveau_event_put(struct nouveau_eventh *handler) { struct nouveau_event *event = handler->event; unsigned long flags; - if (__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) { - spin_lock_irqsave(&event->refs_lock, flags); - if (!--event->index[handler->index].refs) { + u32 m, t; + + if (!__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) + return; + + spin_lock_irqsave(&event->refs_lock, flags); + for (m = handler->types; t = __ffs(m), m; m &= ~(1 << t)) { + if (!--event->refs[handler->index * event->types_nr + t]) { if (event->disable) - event->disable(event, handler->index); + event->disable(event, 1 << t, handler->index); } - spin_unlock_irqrestore(&event->refs_lock, flags); + } + spin_unlock_irqrestore(&event->refs_lock, flags); } void @@ -43,14 +49,20 @@ nouveau_event_get(struct nouveau_eventh *handler) { struct nouveau_event *event = handler->event; unsigned long flags; - if (!__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) { - spin_lock_irqsave(&event->refs_lock, flags); - if (!event->index[handler->index].refs++) { + u32 m, t; + + if (__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) + return; + + spin_lock_irqsave(&event->refs_lock, flags); + for (m = handler->types; t = __ffs(m), m; m &= ~(1 << t)) { + if (!event->refs[handler->index * event->types_nr + t]++) { if (event->enable) - event->enable(event, handler->index); + event->enable(event, 1 << t, handler->index); } - spin_unlock_irqrestore(&event->refs_lock, flags); + } + spin_unlock_irqrestore(&event->refs_lock, flags); } static void @@ -65,38 +77,47 @@ nouveau_event_fini(struct nouveau_eventh *handler) } static int -nouveau_event_init(struct nouveau_event *event, int index, - int (*func)(void *, int), void *priv, +nouveau_event_init(struct nouveau_event *event, u32 types, int index, + int (*func)(void *, u32, int), void *priv, struct nouveau_eventh *handler) { unsigned long flags; + if (types & ~((1 << event->types_nr) - 1)) + return -EINVAL; if (index >= event->index_nr) return -EINVAL; handler->event = event; handler->flags = 0; + handler->types = types; handler->index = index; handler->func = func; handler->priv = priv; spin_lock_irqsave(&event->list_lock, flags); - list_add_tail(&handler->head, &event->index[index].list); + list_add_tail(&handler->head, &event->list[index]); spin_unlock_irqrestore(&event->list_lock, flags); return 0; } int -nouveau_event_new(struct nouveau_event *event, int index, - int (*func)(void *, int), void *priv, +nouveau_event_new(struct nouveau_event *event, u32 types, int index, + int (*func)(void *, u32, int), void *priv, struct nouveau_eventh **phandler) { struct nouveau_eventh *handler; int ret = -ENOMEM; + if (event->check) { + ret = event->check(event, types, index); + if (ret) + return ret; + } + handler = *phandler = kmalloc(sizeof(*handler), GFP_KERNEL); if (handler) { - ret = nouveau_event_init(event, index, func, priv, handler); + ret = nouveau_event_init(event, types, index, func, priv, handler); if (ret) kfree(handler); } @@ -116,7 +137,7 @@ nouveau_event_ref(struct nouveau_eventh *handler, struct nouveau_eventh **ref) } void -nouveau_event_trigger(struct nouveau_event *event, int index) +nouveau_event_trigger(struct nouveau_event *event, u32 types, int index) { struct nouveau_eventh *handler; unsigned long flags; @@ -125,10 +146,15 @@ nouveau_event_trigger(struct nouveau_event *event, int index) return; spin_lock_irqsave(&event->list_lock, flags); - list_for_each_entry(handler, &event->index[index].list, head) { - if (test_bit(NVKM_EVENT_ENABLE, &handler->flags) && - handler->func(handler->priv, index) == NVKM_EVENT_DROP) - nouveau_event_put(handler); + list_for_each_entry(handler, &event->list[index], head) { + if (!test_bit(NVKM_EVENT_ENABLE, &handler->flags)) + continue; + if (!(handler->types & types)) + continue; + if (handler->func(handler->priv, handler->types & types, index) + != NVKM_EVENT_DROP) + continue; + nouveau_event_put(handler); } spin_unlock_irqrestore(&event->list_lock, flags); } @@ -144,20 +170,27 @@ nouveau_event_destroy(struct nouveau_event **pevent) } int -nouveau_event_create(int index_nr, struct nouveau_event **pevent) +nouveau_event_create(int types_nr, int index_nr, struct nouveau_event **pevent) { struct nouveau_event *event; int i; - event = *pevent = kzalloc(sizeof(*event) + index_nr * - sizeof(event->index[0]), GFP_KERNEL); + event = *pevent = kzalloc(sizeof(*event) + (index_nr * types_nr) * + sizeof(event->refs[0]), GFP_KERNEL); if (!event) return -ENOMEM; + event->list = kmalloc(sizeof(*event->list) * index_nr, GFP_KERNEL); + if (!event->list) { + kfree(event); + return -ENOMEM; + } + spin_lock_init(&event->list_lock); spin_lock_init(&event->refs_lock); for (i = 0; i < index_nr; i++) - INIT_LIST_HEAD(&event->index[i].list); + INIT_LIST_HEAD(&event->list[i]); + event->types_nr = types_nr; event->index_nr = index_nr; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/core/namedb.c b/drivers/gpu/drm/nouveau/core/core/namedb.c index 1ce95a8709d..0594a599f6f 100644 --- a/drivers/gpu/drm/nouveau/core/core/namedb.c +++ b/drivers/gpu/drm/nouveau/core/core/namedb.c @@ -167,7 +167,7 @@ int nouveau_namedb_create_(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, u32 pclass, - struct nouveau_oclass *sclass, u32 engcls, + struct nouveau_oclass *sclass, u64 engcls, int length, void **pobject) { struct nouveau_namedb *namedb; diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c index 7f48e288215..12453855590 100644 --- a/drivers/gpu/drm/nouveau/core/core/object.c +++ b/drivers/gpu/drm/nouveau/core/core/object.c @@ -156,7 +156,7 @@ nouveau_object_ctor(struct nouveau_object *parent, } if (ret == 0) { - nv_debug(object, "created\n"); + nv_trace(object, "created\n"); atomic_set(&object->refcount, 1); } @@ -166,7 +166,7 @@ nouveau_object_ctor(struct nouveau_object *parent, static void nouveau_object_dtor(struct nouveau_object *object) { - nv_debug(object, "destroying\n"); + nv_trace(object, "destroying\n"); nv_ofuncs(object)->dtor(object); } @@ -337,7 +337,7 @@ nouveau_object_inc(struct nouveau_object *object) goto fail_self; } - nv_debug(object, "initialised\n"); + nv_trace(object, "initialised\n"); return 0; fail_self: @@ -375,7 +375,7 @@ nouveau_object_decf(struct nouveau_object *object) if (object->parent) nouveau_object_dec(object->parent, false); - nv_debug(object, "stopped\n"); + nv_trace(object, "stopped\n"); return 0; } @@ -411,7 +411,7 @@ nouveau_object_decs(struct nouveau_object *object) } } - nv_debug(object, "suspended\n"); + nv_trace(object, "suspended\n"); return 0; fail_parent: diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c index 313380ce632..dee5d1235e9 100644 --- a/drivers/gpu/drm/nouveau/core/core/parent.c +++ b/drivers/gpu/drm/nouveau/core/core/parent.c @@ -49,7 +49,7 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle, mask = nv_parent(parent)->engine; while (mask) { - int i = ffsll(mask) - 1; + int i = __ffs64(mask); if (nv_iclass(parent, NV_CLIENT_CLASS)) engine = nv_engine(nv_client(parent)->device); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index dd01c6c435d..18c8c7245b7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c @@ -131,8 +131,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, if (ret) return ret; - mmio_base = pci_resource_start(device->pdev, 0); - mmio_size = pci_resource_len(device->pdev, 0); + mmio_base = nv_device_resource_start(device, 0); + mmio_size = nv_device_resource_len(device, 0); /* translate api disable mask into internal mapping */ disable = args->debug0; @@ -185,6 +185,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent, case 0x0e0: case 0x0f0: case 0x100: device->card_type = NV_E0; break; + case 0x110: device->card_type = GM100; break; default: break; } @@ -208,6 +209,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent, case NV_C0: case NV_D0: ret = nvc0_identify(device); break; case NV_E0: ret = nve0_identify(device); break; + case GM100: ret = gm100_identify(device); break; default: ret = -EINVAL; break; @@ -446,6 +448,72 @@ nouveau_device_dtor(struct nouveau_object *object) nouveau_engine_destroy(&device->base); } +resource_size_t +nv_device_resource_start(struct nouveau_device *device, unsigned int bar) +{ + if (nv_device_is_pci(device)) { + return pci_resource_start(device->pdev, bar); + } else { + struct resource *res; + res = platform_get_resource(device->platformdev, + IORESOURCE_MEM, bar); + if (!res) + return 0; + return res->start; + } +} + +resource_size_t +nv_device_resource_len(struct nouveau_device *device, unsigned int bar) +{ + if (nv_device_is_pci(device)) { + return pci_resource_len(device->pdev, bar); + } else { + struct resource *res; + res = platform_get_resource(device->platformdev, + IORESOURCE_MEM, bar); + if (!res) + return 0; + return resource_size(res); + } +} + +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) +{ + if (nv_device_is_pci(device)) { + return device->pdev->irq; + } else { + return platform_get_irq_byname(device->platformdev, + stall ? "stall" : "nonstall"); + } +} + static struct nouveau_oclass nouveau_device_oclass = { .handle = NV_ENGINE(DEVICE, 0x00), @@ -457,8 +525,8 @@ nouveau_device_oclass = { }; int -nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname, - const char *cfg, const char *dbg, +nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name, + const char *sname, const char *cfg, const char *dbg, int length, void **pobject) { struct nouveau_device *device; @@ -476,7 +544,14 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname, if (ret) goto done; - device->pdev = pdev; + switch (type) { + case NOUVEAU_BUS_PCI: + device->pdev = dev; + break; + case NOUVEAU_BUS_PLATFORM: + device->platformdev = dev; + break; + } device->handle = name; device->cfgopt = cfg; device->dbgopt = dbg; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c new file mode 100644 index 00000000000..a520029e25d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c @@ -0,0 +1,106 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include <subdev/bios.h> +#include <subdev/bus.h> +#include <subdev/gpio.h> +#include <subdev/i2c.h> +#include <subdev/clock.h> +#include <subdev/therm.h> +#include <subdev/mxm.h> +#include <subdev/devinit.h> +#include <subdev/mc.h> +#include <subdev/timer.h> +#include <subdev/fb.h> +#include <subdev/ltcg.h> +#include <subdev/ibus.h> +#include <subdev/instmem.h> +#include <subdev/vm.h> +#include <subdev/bar.h> +#include <subdev/pwr.h> +#include <subdev/volt.h> + +#include <engine/device.h> +#include <engine/dmaobj.h> +#include <engine/fifo.h> +#include <engine/software.h> +#include <engine/graph.h> +#include <engine/disp.h> +#include <engine/copy.h> +#include <engine/bsp.h> +#include <engine/vp.h> +#include <engine/ppp.h> +#include <engine/perfmon.h> + +int +gm100_identify(struct nouveau_device *device) +{ + switch (device->chipset) { + case 0x117: + device->cname = "GM107"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; +#if 0 + device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; +#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_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_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_VOLT ] = &nv40_volt_oclass; +#endif + 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; + device->oclass[NVDEV_ENGINE_DISP ] = gm107_disp_oclass; + device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; +#if 0 + device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; +#endif + device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; +#if 0 + device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; + device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; +#endif + break; + default: + nv_fatal(device, "unknown Maxwell chipset\n"); + return -EINVAL; + } + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c index 32113b08c4d..40b29d0214c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c @@ -47,7 +47,7 @@ nv04_identify(struct nouveau_device *device) case 0x04: device->cname = "NV04"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv04_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -60,12 +60,12 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x05: device->cname = "NV05"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv05_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -78,7 +78,7 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; default: nv_fatal(device, "unknown RIVA chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c index 744f15d7e13..5f7c25ff523 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c @@ -48,8 +48,8 @@ nv10_identify(struct nouveau_device *device) case 0x10: device->cname = "NV10"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -60,13 +60,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_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; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x15: device->cname = "NV15"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -79,13 +79,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x16: device->cname = "NV16"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -98,13 +98,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x1a: device->cname = "nForce"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -117,13 +117,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x11: device->cname = "NV11"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -136,13 +136,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x17: device->cname = "NV17"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -155,13 +155,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x1f: device->cname = "nForce2"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -174,13 +174,13 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x18: device->cname = "NV18"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -193,7 +193,7 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; default: nv_fatal(device, "unknown Celsius chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c index 27ba61fb271..75fed11bba0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c @@ -49,8 +49,8 @@ nv20_identify(struct nouveau_device *device) case 0x20: device->cname = "NV20"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -63,13 +63,13 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x25: device->cname = "NV25"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -82,13 +82,13 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x28: device->cname = "NV28"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -101,13 +101,13 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x2a: device->cname = "NV2A"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -120,7 +120,7 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; default: nv_fatal(device, "unknown Kelvin chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c index fd47ace6754..36919d7db7c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c @@ -49,8 +49,8 @@ nv30_identify(struct nouveau_device *device) case 0x30: device->cname = "NV30"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -63,13 +63,13 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x35: device->cname = "NV35"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -82,13 +82,13 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x31: device->cname = "NV31"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -102,13 +102,13 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x36: device->cname = "NV36"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv20_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -122,13 +122,13 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; case 0x34: device->cname = "NV34"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv10_devinit_oclass; device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; @@ -142,7 +142,7 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; break; default: nv_fatal(device, "unknown Rankine chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index 1b653dd74a7..1130a62be2c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c @@ -53,8 +53,8 @@ nv40_identify(struct nouveau_device *device) case 0x40: device->cname = "NV40"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -70,14 +70,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x41: device->cname = "NV41"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -93,14 +93,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x42: device->cname = "NV42"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -116,14 +116,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x43: device->cname = "NV43"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -139,14 +139,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x45: device->cname = "NV45"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -162,14 +162,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x47: device->cname = "G70"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -185,14 +185,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x49: device->cname = "G71"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -208,14 +208,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4b: device->cname = "G73"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -231,14 +231,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x44: device->cname = "NV44"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -254,14 +254,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x46: device->cname = "G72"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -277,14 +277,14 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4a: device->cname = "NV44A"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; @@ -300,18 +300,18 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4c: device->cname = "C61"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; @@ -323,18 +323,18 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4e: device->cname = "C51"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv4e_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv4e_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass; @@ -346,18 +346,18 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x63: device->cname = "C73"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; @@ -369,18 +369,18 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x67: device->cname = "C67"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; @@ -392,18 +392,18 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x68: device->cname = "C68"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv10_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv10_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv4c_mc_oclass; device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; @@ -415,7 +415,7 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv04_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; default: diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c index 81d5c26643d..ef0b0bde1a9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c @@ -60,8 +60,8 @@ nv50_identify(struct nouveau_device *device) case 0x50: device->cname = "G80"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -79,14 +79,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv50_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv50_perfmon_oclass; break; case 0x84: device->cname = "G84"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -107,14 +107,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x86: device->cname = "G86"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv50_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -135,14 +135,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x92: device->cname = "G92"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -163,14 +163,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv84_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x94: device->cname = "G94"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -191,14 +191,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x96: device->cname = "G96"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -219,14 +219,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x98: device->cname = "G98"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -247,14 +247,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xa0: device->cname = "G200"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv50_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -275,14 +275,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva0_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva0_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xaa: device->cname = "MCP77/MCP78"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -303,14 +303,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xac: device->cname = "MCP79/MCP7A"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = nvaa_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -331,14 +331,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nv94_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xa3: device->cname = "GT215"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -361,14 +361,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; case 0xa5: device->cname = "GT216"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -390,14 +390,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; case 0xa8: device->cname = "GT218"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -419,14 +419,14 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; case 0xaf: device->cname = "MCP89"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nva3_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -448,7 +448,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; default: diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index b7d66b59f43..8d55ed633b1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c @@ -60,8 +60,8 @@ nvc0_identify(struct nouveau_device *device) case 0xc0: device->cname = "GF100"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -70,7 +70,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -86,14 +86,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc4: device->cname = "GF104"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -102,7 +102,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -112,20 +112,20 @@ nvc0_identify(struct nouveau_device *device) 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 ] = nvc3_graph_oclass; + device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc3: device->cname = "GF106"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -134,7 +134,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -144,19 +144,19 @@ nvc0_identify(struct nouveau_device *device) 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 ] = nvc3_graph_oclass; + device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xce: device->cname = "GF114"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -165,7 +165,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -175,20 +175,20 @@ nvc0_identify(struct nouveau_device *device) 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 ] = nvc3_graph_oclass; + device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xcf: device->cname = "GF116"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -197,7 +197,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -207,20 +207,20 @@ nvc0_identify(struct nouveau_device *device) 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 ] = nvc3_graph_oclass; + device->oclass[NVDEV_ENGINE_GR ] = nvc4_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc1: device->cname = "GF108"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -229,7 +229,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -244,14 +244,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc8: device->cname = "GF110"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nv92_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nv94_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -260,7 +260,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -276,14 +276,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nva3_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xd9: device->cname = "GF119"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nvd0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -292,7 +292,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -307,14 +307,14 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nvd0_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xd7: device->cname = "GF117"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nvd0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = gf117_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -323,7 +323,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; @@ -336,7 +336,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nvd0_disp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; default: diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 987edbc30a0..2d1e97d4264 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -60,8 +60,8 @@ nve0_identify(struct nouveau_device *device) case 0xe4: device->cname = "GK104"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -70,7 +70,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_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; @@ -81,7 +81,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; @@ -93,8 +93,8 @@ nve0_identify(struct nouveau_device *device) case 0xe7: device->cname = "GK107"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -103,7 +103,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_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; @@ -114,7 +114,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; @@ -126,8 +126,8 @@ nve0_identify(struct nouveau_device *device) case 0xe6: device->cname = "GK106"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -136,7 +136,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_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; @@ -147,7 +147,7 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; + device->oclass[NVDEV_ENGINE_DISP ] = nve0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; @@ -156,11 +156,61 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; break; + case 0xea: + device->cname = "GK20A"; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_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_ENGINE_FIFO ] = gk20a_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass; + device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; + break; case 0xf0: device->cname = "GK110"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; + 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_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_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_VOLT ] = &nv40_volt_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_DISP ] = nvf0_disp_oclass; + device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; + device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; + device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; + device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; + device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; + break; + case 0xf1: + device->cname = "GK110B"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nvd0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -169,7 +219,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_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; @@ -180,22 +230,20 @@ nve0_identify(struct nouveau_device *device) 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_DISP ] = &nvf0_disp_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; device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; -#if 0 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; -#endif device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; break; case 0x108: device->cname = "GK208"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; - device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; - device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; @@ -204,7 +252,7 @@ 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 ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_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; @@ -215,15 +263,13 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass; - device->oclass[NVDEV_ENGINE_DISP ] = &nvf0_disp_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; device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; -#if 0 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; -#endif break; default: nv_fatal(device, "unknown Kepler chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/base.c b/drivers/gpu/drm/nouveau/core/engine/disp/base.c index 7a5cae42834..9c38c5e4050 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/base.c @@ -22,13 +22,89 @@ * Authors: Ben Skeggs */ -#include <engine/disp.h> +#include "priv.h" +#include "outp.h" +#include "conn.h" + +static int +nouveau_disp_hpd_check(struct nouveau_event *event, u32 types, int index) +{ + struct nouveau_disp *disp = event->priv; + 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; + } + } + return -ENOSYS; +} + +int +_nouveau_disp_fini(struct nouveau_object *object, bool suspend) +{ + struct nouveau_disp *disp = (void *)object; + struct nvkm_output *outp; + int ret; + + list_for_each_entry(outp, &disp->outp, head) { + ret = nv_ofuncs(outp)->fini(nv_object(outp), suspend); + if (ret && suspend) + goto fail_outp; + } + + return nouveau_engine_fini(&disp->base, suspend); + +fail_outp: + list_for_each_entry_continue_reverse(outp, &disp->outp, head) { + nv_ofuncs(outp)->init(nv_object(outp)); + } + + return ret; +} + +int +_nouveau_disp_init(struct nouveau_object *object) +{ + struct nouveau_disp *disp = (void *)object; + struct nvkm_output *outp; + int ret; + + ret = nouveau_engine_init(&disp->base); + if (ret) + return ret; + + list_for_each_entry(outp, &disp->outp, head) { + ret = nv_ofuncs(outp)->init(nv_object(outp)); + if (ret) + goto fail_outp; + } + + return ret; + +fail_outp: + list_for_each_entry_continue_reverse(outp, &disp->outp, head) { + nv_ofuncs(outp)->fini(nv_object(outp), false); + } + + return ret; +} void _nouveau_disp_dtor(struct nouveau_object *object) { struct nouveau_disp *disp = (void *)object; + struct nvkm_output *outp, *outt; + nouveau_event_destroy(&disp->vblank); + + if (disp->outp.next) { + list_for_each_entry_safe(outp, outt, &disp->outp, head) { + nouveau_object_ref(NULL, (struct nouveau_object **)&outp); + } + } + nouveau_engine_destroy(&disp->base); } @@ -39,8 +115,15 @@ nouveau_disp_create_(struct nouveau_object *parent, const char *intname, const char *extname, int length, void **pobject) { + struct nouveau_disp_impl *impl = (void *)oclass; + struct nouveau_bios *bios = nouveau_bios(parent); struct nouveau_disp *disp; - int ret; + struct nouveau_oclass **sclass; + struct nouveau_object *object; + struct dcb_output dcbE; + u8 hpd = 0, ver, hdr; + u32 data; + int ret, i; ret = nouveau_engine_create_(parent, engine, oclass, true, intname, extname, length, pobject); @@ -48,5 +131,42 @@ nouveau_disp_create_(struct nouveau_object *parent, if (ret) return ret; - return nouveau_event_create(heads, &disp->vblank); + INIT_LIST_HEAD(&disp->outp); + + /* create output objects for each display path in the vbios */ + i = -1; + while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &dcbE))) { + if (dcbE.type == DCB_OUTPUT_UNUSED) + continue; + if (dcbE.type == DCB_OUTPUT_EOL) + break; + data = dcbE.location << 4 | dcbE.type; + + oclass = nvkm_output_oclass; + sclass = impl->outp; + while (sclass && sclass[0]) { + if (sclass[0]->handle == data) { + oclass = sclass[0]; + break; + } + sclass++; + } + + nouveau_object_ctor(*pobject, *pobject, oclass, + &dcbE, i, &object); + hpd = max(hpd, (u8)(dcbE.connector + 1)); + } + + ret = nouveau_event_create(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); + if (ret) + return ret; + + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/conn.c b/drivers/gpu/drm/nouveau/core/engine/disp/conn.c new file mode 100644 index 00000000000..4ffbc70ecf5 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/conn.c @@ -0,0 +1,172 @@ +/* + * 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 <subdev/gpio.h> + +#include "conn.h" +#include "outp.h" + +static void +nvkm_connector_hpd_work(struct work_struct *w) +{ + struct nvkm_connector *conn = container_of(w, typeof(*conn), hpd.work); + 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); +} + +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; +} + +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); + return nouveau_object_fini(&conn->base, suspend); +} + +int +_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); + } + return ret; +} + +void +_nvkm_connector_dtor(struct nouveau_object *object) +{ + struct nvkm_connector *conn = (void *)object; + nouveau_event_ref(NULL, &conn->hpd.event); + nouveau_object_destroy(&conn->base); +} + +int +nvkm_connector_create_(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, + struct nvbios_connE *info, int index, + int length, void **pobject) +{ + static const u8 hpd[] = { 0x07, 0x08, 0x51, 0x52, 0x5e, 0x5f, 0x60 }; + struct nouveau_gpio *gpio = nouveau_gpio(parent); + struct nouveau_disp *disp = (void *)engine; + struct nvkm_connector *conn; + struct nvkm_output *outp; + struct dcb_gpio_func func; + int ret; + + list_for_each_entry(outp, &disp->outp, head) { + if (outp->conn && outp->conn->index == index) { + atomic_inc(&nv_object(outp->conn)->refcount); + *pobject = outp->conn; + return 1; + } + } + + ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject); + conn = *pobject; + if (ret) + return ret; + + conn->info = *info; + conn->index = index; + + DBG("type %02x loc %d hpd %02x dp %x di %x sr %x lcdid %x\n", + info->type, info->location, info->hpd, info->dp, + info->di, info->sr, info->lcdid); + + if ((info->hpd = ffs(info->hpd))) { + if (--info->hpd >= ARRAY_SIZE(hpd)) { + ERR("hpd %02x unknown\n", info->hpd); + goto done; + } + 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; + } + + ret = nouveau_event_new(gpio->events, NVKM_GPIO_TOGGLED, + func.line, nvkm_connector_hpd, + conn, &conn->hpd.event); + if (ret) { + ERR("func %02x failed, %d\n", info->hpd, ret); + } else { + DBG("func %02x (HPD)\n", info->hpd); + } + } + +done: + INIT_WORK(&conn->hpd.work, nvkm_connector_hpd_work); + return 0; +} + +int +_nvkm_connector_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *info, u32 index, + struct nouveau_object **pobject) +{ + struct nvkm_connector *conn; + int ret; + + ret = nvkm_connector_create(parent, engine, oclass, info, index, &conn); + *pobject = nv_object(conn); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass * +nvkm_connector_oclass = &(struct nvkm_connector_impl) { + .base = { + .handle = 0, + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_connector_ctor, + .dtor = _nvkm_connector_dtor, + .init = _nvkm_connector_init, + .fini = _nvkm_connector_fini, + }, + }, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/conn.h b/drivers/gpu/drm/nouveau/core/engine/disp/conn.h new file mode 100644 index 00000000000..035ebeacbb1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/conn.h @@ -0,0 +1,59 @@ +#ifndef __NVKM_DISP_CONN_H__ +#define __NVKM_DISP_CONN_H__ + +#include "priv.h" + +struct nvkm_connector { + struct nouveau_object base; + struct list_head head; + + struct nvbios_connE info; + int index; + + struct { + struct nouveau_eventh *event; + struct work_struct work; + } hpd; +}; + +#define nvkm_connector_create(p,e,c,b,i,d) \ + nvkm_connector_create_((p), (e), (c), (b), (i), sizeof(**d), (void **)d) +#define nvkm_connector_destroy(d) ({ \ + struct nvkm_connector *disp = (d); \ + _nvkm_connector_dtor(nv_object(disp)); \ +}) +#define nvkm_connector_init(d) ({ \ + struct nvkm_connector *disp = (d); \ + _nvkm_connector_init(nv_object(disp)); \ +}) +#define nvkm_connector_fini(d,s) ({ \ + struct nvkm_connector *disp = (d); \ + _nvkm_connector_fini(nv_object(disp), (s)); \ +}) + +int nvkm_connector_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, struct nvbios_connE *, + int, int, void **); + +int _nvkm_connector_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void _nvkm_connector_dtor(struct nouveau_object *); +int _nvkm_connector_init(struct nouveau_object *); +int _nvkm_connector_fini(struct nouveau_object *, bool); + +struct nvkm_connector_impl { + struct nouveau_oclass base; +}; + +#ifndef MSG +#define MSG(l,f,a...) do { \ + struct nvkm_connector *_conn = (void *)conn; \ + nv_##l(nv_object(conn)->engine, "%02x:%02x%02x: "f, _conn->index, \ + _conn->info.location, _conn->info.type, ##a); \ +} while(0) +#define DBG(f,a...) MSG(debug, f, ##a) +#define ERR(f,a...) MSG(error, f, ##a) +#endif + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c index 1bd4c63369c..5a5b59b2113 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c @@ -30,42 +30,38 @@ #include <engine/disp.h> -#include "dport.h" +#include <core/class.h> -#define DBG(fmt, args...) nv_debug(dp->disp, "DP:%04x:%04x: " fmt, \ - dp->outp->hasht, dp->outp->hashm, ##args) -#define ERR(fmt, args...) nv_error(dp->disp, "DP:%04x:%04x: " fmt, \ - dp->outp->hasht, dp->outp->hashm, ##args) +#include "dport.h" +#include "outpdp.h" /****************************************************************************** * link training *****************************************************************************/ struct dp_state { - const struct nouveau_dp_func *func; - struct nouveau_disp *disp; - struct dcb_output *outp; - struct nvbios_dpout info; - u8 version; - struct nouveau_i2c_port *aux; - int head; - u8 dpcd[4]; + struct nvkm_output_dp *outp; int link_nr; u32 link_bw; u8 stat[6]; u8 conf[4]; + bool pc2; + u8 pc2stat; + u8 pc2conf[2]; }; static int dp_set_link_config(struct dp_state *dp) { - struct nouveau_disp *disp = dp->disp; + struct nvkm_output_dp_impl *impl = (void *)nv_oclass(dp->outp); + struct nvkm_output_dp *outp = dp->outp; + struct nouveau_disp *disp = nouveau_disp(outp); struct nouveau_bios *bios = nouveau_bios(disp); struct nvbios_init init = { - .subdev = nv_subdev(dp->disp), + .subdev = nv_subdev(disp), .bios = bios, .offset = 0x0000, - .outp = dp->outp, - .crtc = dp->head, + .outp = &outp->base.info, + .crtc = -1, .execute = 1, }; u32 lnkcmp; @@ -75,8 +71,8 @@ dp_set_link_config(struct dp_state *dp) DBG("%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); /* set desired link configuration on the source */ - if ((lnkcmp = dp->info.lnkcmp)) { - if (dp->version < 0x30) { + if ((lnkcmp = dp->outp->info.lnkcmp)) { + if (outp->version < 0x30) { while ((dp->link_bw / 10) < nv_ro16(bios, lnkcmp)) lnkcmp += 4; init.offset = nv_ro16(bios, lnkcmp + 2); @@ -89,73 +85,112 @@ dp_set_link_config(struct dp_state *dp) nvbios_exec(&init); } - ret = dp->func->lnk_ctl(dp->disp, dp->outp, dp->head, - dp->link_nr, dp->link_bw / 27000, - dp->dpcd[DPCD_RC02] & - DPCD_RC02_ENHANCED_FRAME_CAP); + ret = impl->lnk_ctl(outp, dp->link_nr, dp->link_bw / 27000, + outp->dpcd[DPCD_RC02] & + DPCD_RC02_ENHANCED_FRAME_CAP); if (ret) { - ERR("lnk_ctl failed with %d\n", ret); + if (ret < 0) + ERR("lnk_ctl failed with %d\n", ret); return ret; } + impl->lnk_pwr(outp, dp->link_nr); + /* set desired link configuration on the sink */ sink[0] = dp->link_bw / 27000; sink[1] = dp->link_nr; - if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP) + if (outp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP) sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN; - return nv_wraux(dp->aux, DPCD_LC00, sink, 2); + return nv_wraux(outp->base.edid, DPCD_LC00_LINK_BW_SET, sink, 2); } static void dp_set_training_pattern(struct dp_state *dp, u8 pattern) { + struct nvkm_output_dp_impl *impl = (void *)nv_oclass(dp->outp); + struct nvkm_output_dp *outp = dp->outp; u8 sink_tp; DBG("training pattern %d\n", pattern); - dp->func->pattern(dp->disp, dp->outp, dp->head, pattern); + impl->pattern(outp, pattern); - nv_rdaux(dp->aux, DPCD_LC02, &sink_tp, 1); + nv_rdaux(outp->base.edid, DPCD_LC02, &sink_tp, 1); sink_tp &= ~DPCD_LC02_TRAINING_PATTERN_SET; sink_tp |= pattern; - nv_wraux(dp->aux, DPCD_LC02, &sink_tp, 1); + nv_wraux(outp->base.edid, DPCD_LC02, &sink_tp, 1); } static int -dp_link_train_commit(struct dp_state *dp) +dp_link_train_commit(struct dp_state *dp, bool pc) { - int i; + struct nvkm_output_dp_impl *impl = (void *)nv_oclass(dp->outp); + struct nvkm_output_dp *outp = dp->outp; + int ret, i; for (i = 0; i < dp->link_nr; i++) { u8 lane = (dp->stat[4 + (i >> 1)] >> ((i & 1) * 4)) & 0xf; + u8 lpc2 = (dp->pc2stat >> (i * 2)) & 0x3; u8 lpre = (lane & 0x0c) >> 2; u8 lvsw = (lane & 0x03) >> 0; + u8 hivs = 3 - lpre; + u8 hipe = 3; + u8 hipc = 3; + + if (lpc2 >= hipc) + lpc2 = hipc | DPCD_LC0F_LANE0_MAX_POST_CURSOR2_REACHED; + if (lpre >= hipe) { + lpre = hipe | DPCD_LC03_MAX_SWING_REACHED; /* yes. */ + lvsw = hivs = 3 - (lpre & 3); + } else + if (lvsw >= hivs) { + lvsw = hivs | DPCD_LC03_MAX_SWING_REACHED; + } dp->conf[i] = (lpre << 3) | lvsw; - if (lvsw == 3) - dp->conf[i] |= DPCD_LC03_MAX_SWING_REACHED; - if (lpre == 3) - dp->conf[i] |= DPCD_LC03_MAX_PRE_EMPHASIS_REACHED; + dp->pc2conf[i >> 1] |= lpc2 << ((i & 1) * 4); - DBG("config lane %d %02x\n", i, dp->conf[i]); - dp->func->drv_ctl(dp->disp, dp->outp, dp->head, i, lvsw, lpre); + DBG("config lane %d %02x %02x\n", i, dp->conf[i], lpc2); + impl->drv_ctl(outp, i, lvsw & 3, lpre & 3, lpc2 & 3); } - return nv_wraux(dp->aux, DPCD_LC03(0), dp->conf, 4); + ret = nv_wraux(outp->base.edid, DPCD_LC03(0), dp->conf, 4); + if (ret) + return ret; + + if (pc) { + ret = nv_wraux(outp->base.edid, DPCD_LC0F, dp->pc2conf, 2); + if (ret) + return ret; + } + + return 0; } static int -dp_link_train_update(struct dp_state *dp, u32 delay) +dp_link_train_update(struct dp_state *dp, bool pc, u32 delay) { + struct nvkm_output_dp *outp = dp->outp; int ret; - udelay(delay); + if (outp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL]) + mdelay(outp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL] * 4); + else + udelay(delay); - ret = nv_rdaux(dp->aux, DPCD_LS02, dp->stat, 6); + ret = nv_rdaux(outp->base.edid, DPCD_LS02, dp->stat, 6); if (ret) return ret; - DBG("status %6ph\n", dp->stat); + if (pc) { + ret = nv_rdaux(outp->base.edid, DPCD_LS0C, &dp->pc2stat, 1); + if (ret) + dp->pc2stat = 0x00; + DBG("status %6ph pc2 %02x\n", dp->stat, dp->pc2stat); + } else { + DBG("status %6ph\n", dp->stat); + } + return 0; } @@ -169,8 +204,8 @@ dp_link_train_cr(struct dp_state *dp) dp_set_training_pattern(dp, 1); do { - if (dp_link_train_commit(dp) || - dp_link_train_update(dp, 100)) + if (dp_link_train_commit(dp, false) || + dp_link_train_update(dp, false, 100)) break; cr_done = true; @@ -196,13 +231,19 @@ dp_link_train_cr(struct dp_state *dp) static int dp_link_train_eq(struct dp_state *dp) { + struct nvkm_output_dp *outp = dp->outp; bool eq_done = false, cr_done = true; int tries = 0, i; - dp_set_training_pattern(dp, 2); + if (outp->dpcd[2] & DPCD_RC02_TPS3_SUPPORTED) + dp_set_training_pattern(dp, 3); + else + dp_set_training_pattern(dp, 2); do { - if (dp_link_train_update(dp, 400)) + if ((tries && + dp_link_train_commit(dp, dp->pc2)) || + dp_link_train_update(dp, dp->pc2, 400)) break; eq_done = !!(dp->stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE); @@ -214,9 +255,6 @@ dp_link_train_eq(struct dp_state *dp) !(lane & DPCD_LS02_LANE0_SYMBOL_LOCKED)) eq_done = false; } - - if (dp_link_train_commit(dp)) - break; } while (!eq_done && cr_done && ++tries <= 5); return eq_done ? 0 : -1; @@ -225,113 +263,109 @@ dp_link_train_eq(struct dp_state *dp) static void dp_link_train_init(struct dp_state *dp, bool spread) { + struct nvkm_output_dp *outp = dp->outp; + struct nouveau_disp *disp = nouveau_disp(outp); + struct nouveau_bios *bios = nouveau_bios(disp); struct nvbios_init init = { - .subdev = nv_subdev(dp->disp), - .bios = nouveau_bios(dp->disp), - .outp = dp->outp, - .crtc = dp->head, + .subdev = nv_subdev(disp), + .bios = bios, + .outp = &outp->base.info, + .crtc = -1, .execute = 1, }; /* set desired spread */ if (spread) - init.offset = dp->info.script[2]; + init.offset = outp->info.script[2]; else - init.offset = dp->info.script[3]; + init.offset = outp->info.script[3]; nvbios_exec(&init); /* pre-train script */ - init.offset = dp->info.script[0]; + init.offset = outp->info.script[0]; nvbios_exec(&init); } static void dp_link_train_fini(struct dp_state *dp) { + struct nvkm_output_dp *outp = dp->outp; + struct nouveau_disp *disp = nouveau_disp(outp); + struct nouveau_bios *bios = nouveau_bios(disp); struct nvbios_init init = { - .subdev = nv_subdev(dp->disp), - .bios = nouveau_bios(dp->disp), - .outp = dp->outp, - .crtc = dp->head, + .subdev = nv_subdev(disp), + .bios = bios, + .outp = &outp->base.info, + .crtc = -1, .execute = 1, }; /* post-train script */ - init.offset = dp->info.script[1], + init.offset = outp->info.script[1], nvbios_exec(&init); } -int -nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, - struct dcb_output *outp, int head, u32 datarate) +static const struct dp_rates { + u32 rate; + u8 bw; + u8 nr; +} nouveau_dp_rates[] = { + { 2160000, 0x14, 4 }, + { 1080000, 0x0a, 4 }, + { 1080000, 0x14, 2 }, + { 648000, 0x06, 4 }, + { 540000, 0x0a, 2 }, + { 540000, 0x14, 1 }, + { 324000, 0x06, 2 }, + { 270000, 0x0a, 1 }, + { 162000, 0x06, 1 }, + {} +}; + +void +nouveau_dp_train(struct work_struct *w) { - struct nouveau_bios *bios = nouveau_bios(disp); - struct nouveau_i2c *i2c = nouveau_i2c(disp); + struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work); + struct nouveau_disp *disp = nouveau_disp(outp); + const struct dp_rates *cfg = nouveau_dp_rates; struct dp_state _dp = { - .disp = disp, - .func = func, .outp = outp, - .head = head, }, *dp = &_dp; - const u32 bw_list[] = { 270000, 162000, 0 }; - const u32 *link_bw = bw_list; - u8 hdr, cnt, len; - u32 data; + u32 datarate = 0; int ret; - /* find the bios displayport data relevant to this output */ - data = nvbios_dpout_match(bios, outp->hasht, outp->hashm, &dp->version, - &hdr, &cnt, &len, &dp->info); - if (!data) { - ERR("bios data not found\n"); - return -EINVAL; - } - - /* acquire the aux channel and fetch some info about the display */ - if (outp->location) - dp->aux = i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(outp->extdev)); - else - dp->aux = i2c->find(i2c, NV_I2C_TYPE_DCBI2C(outp->i2c_index)); - if (!dp->aux) { - ERR("no aux channel?!\n"); - return -ENODEV; + /* bring capabilities within encoder limits */ + if (nv_mclass(disp) < NVD0_DISP_CLASS) + 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; + outp->dpcd[2] |= outp->base.info.dpconf.link_nr; } - - ret = nv_rdaux(dp->aux, 0x00000, dp->dpcd, sizeof(dp->dpcd)); - if (ret) { - /* it's possible the display has been unplugged before we - * get here. we still need to execute the full set of - * vbios scripts, and program the OR at a high enough - * frequency to satisfy the target mode. failure to do - * so results at best in an UPDATE hanging, and at worst - * with PDISP running away to join the circus. - */ - dp->dpcd[1] = link_bw[0] / 27000; - dp->dpcd[2] = 4; - dp->dpcd[3] = 0x00; - ERR("failed to read DPCD\n"); + if (outp->dpcd[1] > outp->base.info.dpconf.link_bw) + outp->dpcd[1] = outp->base.info.dpconf.link_bw; + dp->pc2 = outp->dpcd[2] & DPCD_RC02_TPS3_SUPPORTED; + + /* restrict link config to the lowest required rate, if requested */ + if (datarate) { + datarate = (datarate / 8) * 10; /* 8B/10B coding overhead */ + while (cfg[1].rate >= datarate) + cfg++; } + cfg--; - /* adjust required bandwidth for 8B/10B coding overhead */ - datarate = (datarate / 8) * 10; + /* disable link interrupt handling during link training */ + nouveau_event_put(outp->irq); /* enable down-spreading and execute pre-train script from vbios */ - dp_link_train_init(dp, dp->dpcd[3] & 0x01); + dp_link_train_init(dp, outp->dpcd[3] & 0x01); - /* start off at highest link rate supported by encoder and display */ - while (*link_bw > (dp->dpcd[1] * 27000)) - link_bw++; - - while ((ret = -EIO) && link_bw[0]) { - /* find minimum required lane count at this link rate */ - dp->link_nr = dp->dpcd[2] & DPCD_RC02_MAX_LANE_COUNT; - while ((dp->link_nr >> 1) * link_bw[0] > datarate) - dp->link_nr >>= 1; - - /* drop link rate to minimum with this lane count */ - while ((link_bw[1] * dp->link_nr) > datarate) - link_bw++; - dp->link_bw = link_bw[0]; + while (ret = -EIO, (++cfg)->rate) { + /* select next configuration supported by encoder and sink */ + while (cfg->nr > (outp->dpcd[2] & DPCD_RC02_MAX_LANE_COUNT) || + cfg->bw > (outp->dpcd[DPCD_RC01_MAX_LINK_RATE])) + cfg++; + dp->link_bw = cfg->bw * 27000; + dp->link_nr = cfg->nr; /* program selected link configuration */ ret = dp_set_link_config(dp); @@ -348,17 +382,18 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, */ break; } - - /* retry at lower rate */ - link_bw++; } - /* finish link training */ + /* finish link training and execute post-train script from vbios */ dp_set_training_pattern(dp, 0); if (ret < 0) ERR("link training failed\n"); - /* execute post-train script from vbios */ dp_link_train_fini(dp); - return (ret < 0) ? false : true; + + /* signal completion and enable link interrupt handling */ + DBG("training complete\n"); + atomic_set(&outp->lt.done, 1); + wake_up(&outp->lt.wait); + nouveau_event_get(outp->irq); } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.h b/drivers/gpu/drm/nouveau/core/engine/disp/dport.h index 0e1bbd18ff6..5628d2d5ec7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.h @@ -2,19 +2,18 @@ #define __NVKM_DISP_DPORT_H__ /* DPCD Receiver Capabilities */ -#define DPCD_RC00 0x00000 -#define DPCD_RC00_DPCD_REV 0xff -#define DPCD_RC01 0x00001 -#define DPCD_RC01_MAX_LINK_RATE 0xff +#define DPCD_RC00_DPCD_REV 0x00000 +#define DPCD_RC01_MAX_LINK_RATE 0x00001 #define DPCD_RC02 0x00002 #define DPCD_RC02_ENHANCED_FRAME_CAP 0x80 +#define DPCD_RC02_TPS3_SUPPORTED 0x40 #define DPCD_RC02_MAX_LANE_COUNT 0x1f #define DPCD_RC03 0x00003 #define DPCD_RC03_MAX_DOWNSPREAD 0x01 +#define DPCD_RC0E_AUX_RD_INTERVAL 0x0000e /* DPCD Link Configuration */ -#define DPCD_LC00 0x00100 -#define DPCD_LC00_LINK_BW_SET 0xff +#define DPCD_LC00_LINK_BW_SET 0x00100 #define DPCD_LC01 0x00101 #define DPCD_LC01_ENHANCED_FRAME_EN 0x80 #define DPCD_LC01_LANE_COUNT_SET 0x1f @@ -25,6 +24,16 @@ #define DPCD_LC03_PRE_EMPHASIS_SET 0x18 #define DPCD_LC03_MAX_SWING_REACHED 0x04 #define DPCD_LC03_VOLTAGE_SWING_SET 0x03 +#define DPCD_LC0F 0x0010f +#define DPCD_LC0F_LANE1_MAX_POST_CURSOR2_REACHED 0x40 +#define DPCD_LC0F_LANE1_POST_CURSOR2_SET 0x30 +#define DPCD_LC0F_LANE0_MAX_POST_CURSOR2_REACHED 0x04 +#define DPCD_LC0F_LANE0_POST_CURSOR2_SET 0x03 +#define DPCD_LC10 0x00110 +#define DPCD_LC10_LANE3_MAX_POST_CURSOR2_REACHED 0x40 +#define DPCD_LC10_LANE3_POST_CURSOR2_SET 0x30 +#define DPCD_LC10_LANE2_MAX_POST_CURSOR2_REACHED 0x04 +#define DPCD_LC10_LANE2_POST_CURSOR2_SET 0x03 /* DPCD Link/Sink Status */ #define DPCD_LS02 0x00202 @@ -55,24 +64,12 @@ #define DPCD_LS07_LANE3_VOLTAGE_SWING 0x30 #define DPCD_LS07_LANE2_PRE_EMPHASIS 0x0c #define DPCD_LS07_LANE2_VOLTAGE_SWING 0x03 +#define DPCD_LS0C 0x0020c +#define DPCD_LS0C_LANE3_POST_CURSOR2 0xc0 +#define DPCD_LS0C_LANE2_POST_CURSOR2 0x30 +#define DPCD_LS0C_LANE1_POST_CURSOR2 0x0c +#define DPCD_LS0C_LANE0_POST_CURSOR2 0x03 -struct nouveau_disp; -struct dcb_output; - -struct nouveau_dp_func { - int (*pattern)(struct nouveau_disp *, struct dcb_output *, - int head, int pattern); - int (*lnk_ctl)(struct nouveau_disp *, struct dcb_output *, int head, - int link_nr, int link_bw, bool enh_frame); - int (*drv_ctl)(struct nouveau_disp *, struct dcb_output *, int head, - int lane, int swing, int preem); -}; - -extern const struct nouveau_dp_func nv94_sor_dp_func; -extern const struct nouveau_dp_func nvd0_sor_dp_func; -extern const struct nouveau_dp_func nv50_pior_dp_func; - -int nouveau_dp_train(struct nouveau_disp *, const struct nouveau_dp_func *, - struct dcb_output *, int, u32); +void nouveau_dp_train(struct work_struct *); #endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c new file mode 100644 index 00000000000..9fc7447fec9 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c @@ -0,0 +1,101 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include <engine/software.h> +#include <engine/disp.h> + +#include <core/class.h> + +#include "nv50.h" + +/******************************************************************************* + * Base display object + ******************************************************************************/ + +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 }, + {} +}; + +static struct nouveau_oclass +gm107_disp_base_oclass[] = { + { GM107_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds }, + {} +}; + +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + +static int +gm107_disp_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; + int heads = nv_rd32(parent, 0x022448); + int ret; + + ret = nouveau_disp_create(parent, engine, oclass, heads, + "PDISP", "display", &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_engine(priv)->sclass = gm107_disp_base_oclass; + nv_engine(priv)->cclass = &nv50_disp_cclass; + nv_subdev(priv)->intr = nvd0_disp_intr; + INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); + priv->sclass = gm107_disp_sclass; + priv->head.nr = heads; + priv->dac.nr = 3; + priv->sor.nr = 4; + priv->dac.power = nv50_dac_power; + priv->dac.sense = nv50_dac_sense; + priv->sor.power = nv50_sor_power; + priv->sor.hda_eld = nvd0_hda_eld; + priv->sor.hdmi = nvd0_hdmi_ctrl; + return 0; +} + +struct nouveau_oclass * +gm107_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x07), + .base.base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = gm107_disp_ctor, + .dtor = _nouveau_disp_dtor, + .init = _nouveau_disp_init, + .fini = _nouveau_disp_fini, + }, + .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, +}.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c index 7cf8b134863..a32666ed0c4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include <engine/disp.h> +#include "priv.h" #include <core/event.h> #include <core/class.h> @@ -51,6 +51,14 @@ nv04_disp_scanoutpos(struct nouveau_object *object, u32 mthd, 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()); @@ -78,13 +86,13 @@ nv04_disp_sclass[] = { ******************************************************************************/ static void -nv04_disp_vblank_enable(struct nouveau_event *event, int head) +nv04_disp_vblank_enable(struct nouveau_event *event, int type, int head) { nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000001); } static void -nv04_disp_vblank_disable(struct nouveau_event *event, int head) +nv04_disp_vblank_disable(struct nouveau_event *event, int type, int head) { nv_wr32(event->priv, 0x600140 + (head * 0x2000) , 0x00000000); } @@ -98,12 +106,12 @@ nv04_disp_intr(struct nouveau_subdev *subdev) u32 pvideo; if (crtc0 & 0x00000001) { - nouveau_event_trigger(priv->base.vblank, 0); + nouveau_event_trigger(priv->base.vblank, 1, 0); nv_wr32(priv, 0x600100, 0x00000001); } if (crtc1 & 0x00000001) { - nouveau_event_trigger(priv->base.vblank, 1); + nouveau_event_trigger(priv->base.vblank, 1, 1); nv_wr32(priv, 0x602100, 0x00000001); } @@ -138,13 +146,13 @@ nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass -nv04_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x04), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nv04_disp_oclass = &(struct nouveau_disp_impl) { + .base.handle = NV_ENGINE(DISP, 0x04), + .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv04_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 940eaa5d8b9..2283c442a10 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -26,8 +26,7 @@ #include <core/parent.h> #include <core/handle.h> #include <core/class.h> - -#include <engine/disp.h> +#include <core/enum.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> @@ -227,6 +226,177 @@ nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend) * EVO master channel object ******************************************************************************/ +static void +nv50_disp_mthd_list(struct nv50_disp_priv *priv, int debug, u32 base, int c, + const struct nv50_disp_mthd_list *list, int inst) +{ + struct nouveau_object *disp = nv_object(priv); + int i; + + for (i = 0; list->data[i].mthd; i++) { + if (list->data[i].addr) { + u32 next = nv_rd32(priv, list->data[i].addr + base + 0); + u32 prev = nv_rd32(priv, list->data[i].addr + base + c); + u32 mthd = list->data[i].mthd + (list->mthd * inst); + const char *name = list->data[i].name; + char mods[16]; + + if (prev != next) + snprintf(mods, sizeof(mods), "-> 0x%08x", next); + else + snprintf(mods, sizeof(mods), "%13c", ' '); + + nv_printk_(disp, debug, "\t0x%04x: 0x%08x %s%s%s\n", + mthd, prev, mods, name ? " // " : "", + name ? name : ""); + } + } +} + +void +nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head, + const struct nv50_disp_mthd_chan *chan) +{ + struct nouveau_object *disp = nv_object(priv); + const struct nv50_disp_impl *impl = (void *)disp->oclass; + const struct nv50_disp_mthd_list *list; + int i, j; + + if (debug > nv_subdev(priv)->debug) + return; + + for (i = 0; (list = chan->data[i].mthd) != NULL; i++) { + u32 base = head * chan->addr; + for (j = 0; j < chan->data[i].nr; j++, base += list->addr) { + const char *cname = chan->name; + const char *sname = ""; + char cname_[16], sname_[16]; + + if (chan->addr) { + snprintf(cname_, sizeof(cname_), "%s %d", + chan->name, head); + cname = cname_; + } + + if (chan->data[i].nr > 1) { + snprintf(sname_, sizeof(sname_), " - %s %d", + chan->data[i].name, j); + sname = sname_; + } + + nv_printk_(disp, debug, "%s%s:\n", cname, sname); + nv50_disp_mthd_list(priv, debug, base, impl->mthd.prev, + list, j); + } + } +} + +const struct nv50_disp_mthd_list +nv50_disp_mast_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x000000 }, + { 0x0084, 0x610bb8 }, + { 0x0088, 0x610b9c }, + { 0x008c, 0x000000 }, + {} + } +}; + +static const struct nv50_disp_mthd_list +nv50_disp_mast_mthd_dac = { + .mthd = 0x0080, + .addr = 0x000008, + .data = { + { 0x0400, 0x610b58 }, + { 0x0404, 0x610bdc }, + { 0x0420, 0x610828 }, + {} + } +}; + +const struct nv50_disp_mthd_list +nv50_disp_mast_mthd_sor = { + .mthd = 0x0040, + .addr = 0x000008, + .data = { + { 0x0600, 0x610b70 }, + {} + } +}; + +const struct nv50_disp_mthd_list +nv50_disp_mast_mthd_pior = { + .mthd = 0x0040, + .addr = 0x000008, + .data = { + { 0x0700, 0x610b80 }, + {} + } +}; + +static const struct nv50_disp_mthd_list +nv50_disp_mast_mthd_head = { + .mthd = 0x0400, + .addr = 0x000540, + .data = { + { 0x0800, 0x610ad8 }, + { 0x0804, 0x610ad0 }, + { 0x0808, 0x610a48 }, + { 0x080c, 0x610a78 }, + { 0x0810, 0x610ac0 }, + { 0x0814, 0x610af8 }, + { 0x0818, 0x610b00 }, + { 0x081c, 0x610ae8 }, + { 0x0820, 0x610af0 }, + { 0x0824, 0x610b08 }, + { 0x0828, 0x610b10 }, + { 0x082c, 0x610a68 }, + { 0x0830, 0x610a60 }, + { 0x0834, 0x000000 }, + { 0x0838, 0x610a40 }, + { 0x0840, 0x610a24 }, + { 0x0844, 0x610a2c }, + { 0x0848, 0x610aa8 }, + { 0x084c, 0x610ab0 }, + { 0x0860, 0x610a84 }, + { 0x0864, 0x610a90 }, + { 0x0868, 0x610b18 }, + { 0x086c, 0x610b20 }, + { 0x0870, 0x610ac8 }, + { 0x0874, 0x610a38 }, + { 0x0880, 0x610a58 }, + { 0x0884, 0x610a9c }, + { 0x08a0, 0x610a70 }, + { 0x08a4, 0x610a50 }, + { 0x08a8, 0x610ae0 }, + { 0x08c0, 0x610b28 }, + { 0x08c4, 0x610b30 }, + { 0x08c8, 0x610b40 }, + { 0x08d4, 0x610b38 }, + { 0x08d8, 0x610b48 }, + { 0x08dc, 0x610b50 }, + { 0x0900, 0x610a18 }, + { 0x0904, 0x610ab8 }, + {} + } +}; + +static const struct nv50_disp_mthd_chan +nv50_disp_mast_mthd_chan = { + .name = "Core", + .addr = 0x000000, + .data = { + { "Global", 1, &nv50_disp_mast_mthd_base }, + { "DAC", 3, &nv50_disp_mast_mthd_dac }, + { "SOR", 2, &nv50_disp_mast_mthd_sor }, + { "PIOR", 3, &nv50_disp_mast_mthd_pior }, + { "HEAD", 2, &nv50_disp_mast_mthd_head }, + {} + } +}; + static int nv50_disp_mast_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -323,6 +493,56 @@ nv50_disp_mast_ofuncs = { * EVO sync channel objects ******************************************************************************/ +static const struct nv50_disp_mthd_list +nv50_disp_sync_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x000000 }, + { 0x0084, 0x0008c4 }, + { 0x0088, 0x0008d0 }, + { 0x008c, 0x0008dc }, + { 0x0090, 0x0008e4 }, + { 0x0094, 0x610884 }, + { 0x00a0, 0x6108a0 }, + { 0x00a4, 0x610878 }, + { 0x00c0, 0x61086c }, + { 0x00e0, 0x610858 }, + { 0x00e4, 0x610860 }, + { 0x00e8, 0x6108ac }, + { 0x00ec, 0x6108b4 }, + { 0x0100, 0x610894 }, + { 0x0110, 0x6108bc }, + { 0x0114, 0x61088c }, + {} + } +}; + +const struct nv50_disp_mthd_list +nv50_disp_sync_mthd_image = { + .mthd = 0x0400, + .addr = 0x000000, + .data = { + { 0x0800, 0x6108f0 }, + { 0x0804, 0x6108fc }, + { 0x0808, 0x61090c }, + { 0x080c, 0x610914 }, + { 0x0810, 0x610904 }, + {} + } +}; + +static const struct nv50_disp_mthd_chan +nv50_disp_sync_mthd_chan = { + .name = "Base", + .addr = 0x000540, + .data = { + { "Global", 1, &nv50_disp_sync_mthd_base }, + { "Image", 2, &nv50_disp_sync_mthd_image }, + {} + } +}; + static int nv50_disp_sync_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -362,6 +582,44 @@ nv50_disp_sync_ofuncs = { * EVO overlay channel objects ******************************************************************************/ +const struct nv50_disp_mthd_list +nv50_disp_ovly_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x000000 }, + { 0x0084, 0x0009a0 }, + { 0x0088, 0x0009c0 }, + { 0x008c, 0x0009c8 }, + { 0x0090, 0x6109b4 }, + { 0x0094, 0x610970 }, + { 0x00a0, 0x610998 }, + { 0x00a4, 0x610964 }, + { 0x00c0, 0x610958 }, + { 0x00e0, 0x6109a8 }, + { 0x00e4, 0x6109d0 }, + { 0x00e8, 0x6109d8 }, + { 0x0100, 0x61094c }, + { 0x0104, 0x610984 }, + { 0x0108, 0x61098c }, + { 0x0800, 0x6109f8 }, + { 0x0808, 0x610a08 }, + { 0x080c, 0x610a10 }, + { 0x0810, 0x610a00 }, + {} + } +}; + +static const struct nv50_disp_mthd_chan +nv50_disp_ovly_mthd_chan = { + .name = "Overlay", + .addr = 0x000540, + .data = { + { "Global", 1, &nv50_disp_ovly_mthd_base }, + {} + } +}; + static int nv50_disp_ovly_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -571,13 +829,13 @@ nv50_disp_base_scanoutpos(struct nouveau_object *object, u32 mthd, } static void -nv50_disp_base_vblank_enable(struct nouveau_event *event, int head) +nv50_disp_base_vblank_enable(struct nouveau_event *event, int type, int head) { nv_mask(event->priv, 0x61002c, (4 << head), (4 << head)); } static void -nv50_disp_base_vblank_disable(struct nouveau_event *event, int head) +nv50_disp_base_vblank_disable(struct nouveau_event *event, int type, int head) { nv_mask(event->priv, 0x61002c, (4 << head), 0); } @@ -782,40 +1040,94 @@ nv50_disp_cclass = { * Display engine implementation ******************************************************************************/ -static void -nv50_disp_intr_error(struct nv50_disp_priv *priv) -{ - u32 channels = (nv_rd32(priv, 0x610020) & 0x001f0000) >> 16; - u32 addr, data; - int chid; - - for (chid = 0; chid < 5; chid++) { - if (!(channels & (1 << chid))) - continue; +static const struct nouveau_enum +nv50_disp_intr_error_type[] = { + { 3, "ILLEGAL_MTHD" }, + { 4, "INVALID_VALUE" }, + { 5, "INVALID_STATE" }, + { 7, "INVALID_HANDLE" }, + {} +}; - nv_wr32(priv, 0x610020, 0x00010000 << chid); - addr = nv_rd32(priv, 0x610080 + (chid * 0x08)); - data = nv_rd32(priv, 0x610084 + (chid * 0x08)); - nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000); +static const struct nouveau_enum +nv50_disp_intr_error_code[] = { + { 0x00, "" }, + {} +}; - nv_error(priv, "chid %d mthd 0x%04x data 0x%08x 0x%08x\n", - chid, addr & 0xffc, data, addr); +static void +nv50_disp_intr_error(struct nv50_disp_priv *priv, int chid) +{ + struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass; + u32 data = nv_rd32(priv, 0x610084 + (chid * 0x08)); + u32 addr = nv_rd32(priv, 0x610080 + (chid * 0x08)); + u32 code = (addr & 0x00ff0000) >> 16; + u32 type = (addr & 0x00007000) >> 12; + u32 mthd = (addr & 0x00000ffc); + const struct nouveau_enum *ec, *et; + char ecunk[6], etunk[6]; + + et = nouveau_enum_find(nv50_disp_intr_error_type, type); + if (!et) + snprintf(etunk, sizeof(etunk), "UNK%02X", type); + + ec = nouveau_enum_find(nv50_disp_intr_error_code, code); + if (!ec) + snprintf(ecunk, sizeof(ecunk), "UNK%02X", code); + + nv_error(priv, "%s [%s] chid %d mthd 0x%04x data 0x%08x\n", + et ? et->name : etunk, ec ? ec->name : ecunk, + chid, mthd, data); + + if (chid == 0) { + switch (mthd) { + case 0x0080: + nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0, + impl->mthd.core); + break; + default: + break; + } + } else + if (chid <= 2) { + switch (mthd) { + case 0x0080: + nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1, + impl->mthd.base); + break; + default: + break; + } + } else + if (chid <= 4) { + switch (mthd) { + case 0x0080: + nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 3, + impl->mthd.ovly); + break; + default: + break; + } } + + nv_wr32(priv, 0x610020, 0x00010000 << chid); + nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000); } -static u16 -exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, - struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, +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, struct nvbios_outp *info) { struct nouveau_bios *bios = nouveau_bios(priv); - u16 mask, type, data; + struct nvkm_output *outp; + u16 mask, type; - if (outp < 4) { + if (or < 4) { type = DCB_OUTPUT_ANALOG; mask = 0; } else - if (outp < 8) { + if (or < 8) { switch (ctrl & 0x00000f00) { case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; @@ -825,45 +1137,48 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break; default: nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); - return 0x0000; + return NULL; } - outp -= 4; + or -= 4; } else { - outp = outp - 8; + or = or - 8; type = 0x0010; mask = 0; switch (ctrl & 0x00000f00) { - case 0x00000000: type |= priv->pior.type[outp]; break; + case 0x00000000: type |= priv->pior.type[or]; break; default: nv_error(priv, "unknown PIOR mc 0x%08x\n", ctrl); - return 0x0000; + return NULL; } } mask = 0x00c0 & (mask << 6); - mask |= 0x0001 << outp; + mask |= 0x0001 << or; mask |= 0x0100 << head; - data = dcb_outp_match(bios, type, mask, ver, hdr, dcb); - if (!data) - return 0x0000; - - /* off-chip encoders require matching the exact encoder type */ - if (dcb->location != 0) - type |= dcb->extdev << 8; + list_for_each_entry(outp, &priv->base.outp, head) { + if ((outp->info.hasht & 0xff) == type && + (outp->info.hashm & mask) == mask) { + *data = nvbios_outp_match(bios, outp->info.hasht, + outp->info.hashm, + ver, hdr, cnt, len, info); + if (!*data) + return NULL; + return outp; + } + } - return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info); + return NULL; } -static bool +static struct nvkm_output * exec_script(struct nv50_disp_priv *priv, int head, int id) { struct nouveau_bios *bios = nouveau_bios(priv); + struct nvkm_output *outp; struct nvbios_outp info; - struct dcb_output dcb; u8 ver, hdr, cnt, len; - u16 data; - u32 ctrl = 0x00000000; + u32 data, ctrl = 0; u32 reg; int i; @@ -893,36 +1208,35 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) } if (!(ctrl & (1 << head))) - return false; + return NULL; i--; - data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); - if (data) { + outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info); + if (outp) { struct nvbios_init init = { .subdev = nv_subdev(priv), .bios = bios, .offset = info.script[id], - .outp = &dcb, + .outp = &outp->info, .crtc = head, .execute = 1, }; - return nvbios_exec(&init) == 0; + nvbios_exec(&init); } - return false; + return outp; } -static u32 -exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, - struct dcb_output *outp) +static struct nvkm_output * +exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf) { struct nouveau_bios *bios = nouveau_bios(priv); + struct nvkm_output *outp; struct nvbios_outp info1; struct nvbios_ocfg info2; u8 ver, hdr, cnt, len; - u32 ctrl = 0x00000000; - u32 data, conf = ~0; + u32 data, ctrl = 0; u32 reg; int i; @@ -952,37 +1266,37 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, } if (!(ctrl & (1 << head))) - return conf; + return NULL; i--; - data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1); - if (!data) - return conf; + outp = exec_lookup(priv, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1); + if (!outp) + return NULL; - if (outp->location == 0) { - switch (outp->type) { + if (outp->info.location == 0) { + switch (outp->info.type) { case DCB_OUTPUT_TMDS: - conf = (ctrl & 0x00000f00) >> 8; + *conf = (ctrl & 0x00000f00) >> 8; if (pclk >= 165000) - conf |= 0x0100; + *conf |= 0x0100; break; case DCB_OUTPUT_LVDS: - conf = priv->sor.lvdsconf; + *conf = priv->sor.lvdsconf; break; case DCB_OUTPUT_DP: - conf = (ctrl & 0x00000f00) >> 8; + *conf = (ctrl & 0x00000f00) >> 8; break; case DCB_OUTPUT_ANALOG: default: - conf = 0x00ff; + *conf = 0x00ff; break; } } else { - conf = (ctrl & 0x00000f00) >> 8; + *conf = (ctrl & 0x00000f00) >> 8; pclk = pclk / 2; } - data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2); + data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); if (data && id < 0xff) { data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); if (data) { @@ -990,7 +1304,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, .subdev = nv_subdev(priv), .bios = bios, .offset = data, - .outp = outp, + .outp = &outp->info, .crtc = head, .execute = 1, }; @@ -999,7 +1313,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, } } - return conf; + return outp; } static void @@ -1011,7 +1325,35 @@ nv50_disp_intr_unk10_0(struct nv50_disp_priv *priv, int head) static void nv50_disp_intr_unk20_0(struct nv50_disp_priv *priv, int head) { - exec_script(priv, head, 2); + struct nvkm_output *outp = exec_script(priv, head, 2); + + /* the binary driver does this outside of the supervisor handling + * (after the third supervisor from a detach). we (currently?) + * allow both detach/attach to happen in the same set of + * supervisor interrupts, so it would make sense to execute this + * (full power down?) script after all the detach phases of the + * supervisor handling. like with training if needed from the + * second supervisor, nvidia doesn't do this, so who knows if it's + * entirely safe, but it does appear to work.. + * + * without this script being run, on some configurations i've + * seen, switching from DP to TMDS on a DP connector may result + * in a blank screen (SOR_PWR off/on can restore it) + */ + if (outp && outp->info.type == DCB_OUTPUT_DP) { + struct nvkm_output_dp *outpdp = (void *)outp; + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = nouveau_bios(priv), + .outp = &outp->info, + .crtc = head, + .offset = outpdp->info.script[4], + .execute = 1, + }; + + nvbios_exec(&init); + atomic_set(&outpdp->lt.done, 0); + } } static void @@ -1133,56 +1475,83 @@ nv50_disp_intr_unk20_2_dp(struct nv50_disp_priv *priv, static void nv50_disp_intr_unk20_2(struct nv50_disp_priv *priv, int head) { - struct dcb_output outp; + struct nvkm_output *outp; u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; u32 hval, hreg = 0x614200 + (head * 0x800); u32 oval, oreg; - u32 mask; - u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp); - if (conf != ~0) { - if (outp.location == 0 && outp.type == DCB_OUTPUT_DP) { - u32 soff = (ffs(outp.or) - 1) * 0x08; - u32 ctrl = nv_rd32(priv, 0x610798 + soff); - u32 datarate; - - switch ((ctrl & 0x000f0000) >> 16) { - case 6: datarate = pclk * 30 / 8; break; - case 5: datarate = pclk * 24 / 8; break; - case 2: - default: - datarate = pclk * 18 / 8; - break; - } + u32 mask, conf; - nouveau_dp_train(&priv->base, priv->sor.dp, - &outp, head, datarate); - } + outp = exec_clkcmp(priv, head, 0xff, pclk, &conf); + if (!outp) + return; + + /* we allow both encoder attach and detach operations to occur + * within a single supervisor (ie. modeset) sequence. the + * encoder detach scripts quite often switch off power to the + * lanes, which requires the link to be re-trained. + * + * this is not generally an issue as the sink "must" (heh) + * signal an irq when it's lost sync so the driver can + * re-train. + * + * however, on some boards, if one does not configure at least + * the gpu side of the link *before* attaching, then various + * things can go horribly wrong (PDISP disappearing from mmio, + * third supervisor never happens, etc). + * + * the solution is simply to retrain here, if necessary. last + * i checked, the binary driver userspace does not appear to + * trigger this situation (it forces an UPDATE between steps). + */ + if (outp->info.type == DCB_OUTPUT_DP) { + u32 soff = (ffs(outp->info.or) - 1) * 0x08; + u32 ctrl, datarate; - exec_clkcmp(priv, head, 0, pclk, &outp); - - if (!outp.location && outp.type == DCB_OUTPUT_ANALOG) { - oreg = 0x614280 + (ffs(outp.or) - 1) * 0x800; - oval = 0x00000000; - hval = 0x00000000; - mask = 0xffffffff; - } else - if (!outp.location) { - if (outp.type == DCB_OUTPUT_DP) - nv50_disp_intr_unk20_2_dp(priv, &outp, pclk); - oreg = 0x614300 + (ffs(outp.or) - 1) * 0x800; - oval = (conf & 0x0100) ? 0x00000101 : 0x00000000; - hval = 0x00000000; - mask = 0x00000707; + if (outp->info.location == 0) { + ctrl = nv_rd32(priv, 0x610794 + soff); + soff = 1; } else { - oreg = 0x614380 + (ffs(outp.or) - 1) * 0x800; - oval = 0x00000001; - hval = 0x00000001; - mask = 0x00000707; + ctrl = nv_rd32(priv, 0x610b80 + soff); + soff = 2; } - nv_mask(priv, hreg, 0x0000000f, hval); - nv_mask(priv, oreg, mask, oval); + switch ((ctrl & 0x000f0000) >> 16) { + case 6: datarate = pclk * 30; break; + case 5: datarate = pclk * 24; break; + case 2: + default: + datarate = pclk * 18; + break; + } + + if (nvkm_output_dp_train(outp, datarate / soff, true)) + ERR("link not trained before attach\n"); } + + exec_clkcmp(priv, head, 0, pclk, &conf); + + if (!outp->info.location && outp->info.type == DCB_OUTPUT_ANALOG) { + oreg = 0x614280 + (ffs(outp->info.or) - 1) * 0x800; + oval = 0x00000000; + hval = 0x00000000; + mask = 0xffffffff; + } else + if (!outp->info.location) { + if (outp->info.type == DCB_OUTPUT_DP) + nv50_disp_intr_unk20_2_dp(priv, &outp->info, pclk); + oreg = 0x614300 + (ffs(outp->info.or) - 1) * 0x800; + oval = (conf & 0x0100) ? 0x00000101 : 0x00000000; + hval = 0x00000000; + mask = 0x00000707; + } else { + oreg = 0x614380 + (ffs(outp->info.or) - 1) * 0x800; + oval = 0x00000001; + hval = 0x00000001; + mask = 0x00000707; + } + + nv_mask(priv, hreg, 0x0000000f, hval); + nv_mask(priv, oreg, mask, oval); } /* If programming a TMDS output on a SOR that can also be configured for @@ -1210,30 +1579,16 @@ nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp static void nv50_disp_intr_unk40_0(struct nv50_disp_priv *priv, int head) { - struct dcb_output outp; + struct nvkm_output *outp; u32 pclk = nv_rd32(priv, 0x610ad0 + (head * 0x540)) & 0x3fffff; - if (exec_clkcmp(priv, head, 1, pclk, &outp) != ~0) { - if (outp.location == 0 && outp.type == DCB_OUTPUT_TMDS) - nv50_disp_intr_unk40_0_tmds(priv, &outp); - else - if (outp.location == 1 && outp.type == DCB_OUTPUT_DP) { - u32 soff = (ffs(outp.or) - 1) * 0x08; - u32 ctrl = nv_rd32(priv, 0x610b84 + soff); - u32 datarate; - - switch ((ctrl & 0x000f0000) >> 16) { - case 6: datarate = pclk * 30 / 8; break; - case 5: datarate = pclk * 24 / 8; break; - case 2: - default: - datarate = pclk * 18 / 8; - break; - } + u32 conf; - nouveau_dp_train(&priv->base, priv->pior.dp, - &outp, head, datarate); - } - } + outp = exec_clkcmp(priv, head, 1, pclk, &conf); + if (!outp) + return; + + if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS) + nv50_disp_intr_unk40_0_tmds(priv, &outp->info); } void @@ -1241,12 +1596,14 @@ nv50_disp_intr_supervisor(struct work_struct *work) { struct nv50_disp_priv *priv = container_of(work, struct nv50_disp_priv, supervisor); + struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass; u32 super = nv_rd32(priv, 0x610030); int head; nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super); if (priv->super & 0x00000010) { + nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core); for (head = 0; head < priv->head.nr; head++) { if (!(super & (0x00000020 << head))) continue; @@ -1290,19 +1647,20 @@ nv50_disp_intr(struct nouveau_subdev *subdev) u32 intr0 = nv_rd32(priv, 0x610020); u32 intr1 = nv_rd32(priv, 0x610024); - if (intr0 & 0x001f0000) { - nv50_disp_intr_error(priv); - intr0 &= ~0x001f0000; + while (intr0 & 0x001f0000) { + u32 chid = __ffs(intr0 & 0x001f0000) - 16; + nv50_disp_intr_error(priv, chid); + intr0 &= ~(0x00010000 << chid); } if (intr1 & 0x00000004) { - nouveau_event_trigger(priv->base.vblank, 0); + nouveau_event_trigger(priv->base.vblank, 1, 0); nv_wr32(priv, 0x610024, 0x00000004); intr1 &= ~0x00000004; } if (intr1 & 0x00000008) { - nouveau_event_trigger(priv->base.vblank, 1); + nouveau_event_trigger(priv->base.vblank, 1, 1); nv_wr32(priv, 0x610024, 0x00000008); intr1 &= ~0x00000008; } @@ -1342,17 +1700,27 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; return 0; } -struct nouveau_oclass -nv50_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nv50_disp_outp_sclass[] = { + &nv50_pior_dp_impl.base.base, + NULL +}; + +struct nouveau_oclass * +nv50_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x50), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 d31d426ea1f..1a886472b6f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h @@ -8,9 +8,21 @@ #include <core/event.h> #include <engine/dmaobj.h> -#include <engine/disp.h> #include "dport.h" +#include "priv.h" +#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; +}; struct nv50_disp_priv { struct nouveau_disp base; @@ -33,13 +45,11 @@ struct nv50_disp_priv { int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); u32 lvdsconf; - const struct nouveau_dp_func *dp; } sor; struct { int nr; int (*power)(struct nv50_disp_priv *, int ext, u32 data); u8 type[3]; - const struct nouveau_dp_func *dp; } pior; }; @@ -124,21 +134,60 @@ struct nv50_disp_pioc { struct nv50_disp_chan base; }; +struct nv50_disp_mthd_list { + u32 mthd; + u32 addr; + struct { + u32 mthd; + u32 addr; + const char *name; + } data[]; +}; + +struct nv50_disp_mthd_chan { + const char *name; + u32 addr; + struct { + const char *name; + int nr; + const struct nv50_disp_mthd_list *mthd; + } data[]; +}; + extern struct nouveau_ofuncs nv50_disp_mast_ofuncs; +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 const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image; extern struct nouveau_ofuncs nv50_disp_ovly_ofuncs; +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 nouveau_ofuncs nv50_disp_base_ofuncs; 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 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 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 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[]; @@ -147,4 +196,17 @@ 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 nv50_disp_mthd_chan nve0_disp_mast_mthd_chan; +extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan; + +extern struct nvkm_output_dp_impl nv50_pior_dp_impl; +extern struct nouveau_oclass *nv50_disp_outp_sclass[]; + +extern struct nvkm_output_dp_impl nv94_sor_dp_impl; +int nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int); +extern struct nouveau_oclass *nv94_disp_outp_sclass[]; + +extern struct nvkm_output_dp_impl nvd0_sor_dp_impl; +extern struct nouveau_oclass *nvd0_disp_outp_sclass[]; + #endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index ef9ce300a49..1cc62e43468 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c @@ -29,6 +29,179 @@ #include "nv50.h" +/******************************************************************************* + * EVO master channel object + ******************************************************************************/ + +const struct nv50_disp_mthd_list +nv84_disp_mast_mthd_dac = { + .mthd = 0x0080, + .addr = 0x000008, + .data = { + { 0x0400, 0x610b58 }, + { 0x0404, 0x610bdc }, + { 0x0420, 0x610bc4 }, + {} + } +}; + +const struct nv50_disp_mthd_list +nv84_disp_mast_mthd_head = { + .mthd = 0x0400, + .addr = 0x000540, + .data = { + { 0x0800, 0x610ad8 }, + { 0x0804, 0x610ad0 }, + { 0x0808, 0x610a48 }, + { 0x080c, 0x610a78 }, + { 0x0810, 0x610ac0 }, + { 0x0814, 0x610af8 }, + { 0x0818, 0x610b00 }, + { 0x081c, 0x610ae8 }, + { 0x0820, 0x610af0 }, + { 0x0824, 0x610b08 }, + { 0x0828, 0x610b10 }, + { 0x082c, 0x610a68 }, + { 0x0830, 0x610a60 }, + { 0x0834, 0x000000 }, + { 0x0838, 0x610a40 }, + { 0x0840, 0x610a24 }, + { 0x0844, 0x610a2c }, + { 0x0848, 0x610aa8 }, + { 0x084c, 0x610ab0 }, + { 0x085c, 0x610c5c }, + { 0x0860, 0x610a84 }, + { 0x0864, 0x610a90 }, + { 0x0868, 0x610b18 }, + { 0x086c, 0x610b20 }, + { 0x0870, 0x610ac8 }, + { 0x0874, 0x610a38 }, + { 0x0878, 0x610c50 }, + { 0x0880, 0x610a58 }, + { 0x0884, 0x610a9c }, + { 0x089c, 0x610c68 }, + { 0x08a0, 0x610a70 }, + { 0x08a4, 0x610a50 }, + { 0x08a8, 0x610ae0 }, + { 0x08c0, 0x610b28 }, + { 0x08c4, 0x610b30 }, + { 0x08c8, 0x610b40 }, + { 0x08d4, 0x610b38 }, + { 0x08d8, 0x610b48 }, + { 0x08dc, 0x610b50 }, + { 0x0900, 0x610a18 }, + { 0x0904, 0x610ab8 }, + { 0x0910, 0x610c70 }, + { 0x0914, 0x610c78 }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nv84_disp_mast_mthd_chan = { + .name = "Core", + .addr = 0x000000, + .data = { + { "Global", 1, &nv50_disp_mast_mthd_base }, + { "DAC", 3, &nv84_disp_mast_mthd_dac }, + { "SOR", 2, &nv50_disp_mast_mthd_sor }, + { "PIOR", 3, &nv50_disp_mast_mthd_pior }, + { "HEAD", 2, &nv84_disp_mast_mthd_head }, + {} + } +}; + +/******************************************************************************* + * EVO sync channel objects + ******************************************************************************/ + +static const struct nv50_disp_mthd_list +nv84_disp_sync_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x000000 }, + { 0x0084, 0x0008c4 }, + { 0x0088, 0x0008d0 }, + { 0x008c, 0x0008dc }, + { 0x0090, 0x0008e4 }, + { 0x0094, 0x610884 }, + { 0x00a0, 0x6108a0 }, + { 0x00a4, 0x610878 }, + { 0x00c0, 0x61086c }, + { 0x00c4, 0x610800 }, + { 0x00c8, 0x61080c }, + { 0x00cc, 0x610818 }, + { 0x00e0, 0x610858 }, + { 0x00e4, 0x610860 }, + { 0x00e8, 0x6108ac }, + { 0x00ec, 0x6108b4 }, + { 0x00fc, 0x610824 }, + { 0x0100, 0x610894 }, + { 0x0104, 0x61082c }, + { 0x0110, 0x6108bc }, + { 0x0114, 0x61088c }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nv84_disp_sync_mthd_chan = { + .name = "Base", + .addr = 0x000540, + .data = { + { "Global", 1, &nv84_disp_sync_mthd_base }, + { "Image", 2, &nv50_disp_sync_mthd_image }, + {} + } +}; + +/******************************************************************************* + * EVO overlay channel objects + ******************************************************************************/ + +static const struct nv50_disp_mthd_list +nv84_disp_ovly_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x000000 }, + { 0x0084, 0x6109a0 }, + { 0x0088, 0x6109c0 }, + { 0x008c, 0x6109c8 }, + { 0x0090, 0x6109b4 }, + { 0x0094, 0x610970 }, + { 0x00a0, 0x610998 }, + { 0x00a4, 0x610964 }, + { 0x00c0, 0x610958 }, + { 0x00e0, 0x6109a8 }, + { 0x00e4, 0x6109d0 }, + { 0x00e8, 0x6109d8 }, + { 0x0100, 0x61094c }, + { 0x0104, 0x610984 }, + { 0x0108, 0x61098c }, + { 0x0800, 0x6109f8 }, + { 0x0808, 0x610a08 }, + { 0x080c, 0x610a10 }, + { 0x0810, 0x610a00 }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nv84_disp_ovly_mthd_chan = { + .name = "Overlay", + .addr = 0x000540, + .data = { + { "Global", 1, &nv84_disp_ovly_mthd_base }, + {} + } +}; + +/******************************************************************************* + * Base display object + ******************************************************************************/ + static struct nouveau_oclass nv84_disp_sclass[] = { { NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, @@ -59,6 +232,10 @@ nv84_disp_base_oclass[] = { {} }; +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + static int nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -87,17 +264,21 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hdmi = nv84_hdmi_ctrl; priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; return 0; } -struct nouveau_oclass -nv84_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x82), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nv84_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x82), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv84_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 a518543c00a..4f718a9f5ae 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c @@ -29,6 +29,38 @@ #include "nv50.h" +/******************************************************************************* + * EVO master channel object + ******************************************************************************/ + +const struct nv50_disp_mthd_list +nv94_disp_mast_mthd_sor = { + .mthd = 0x0040, + .addr = 0x000008, + .data = { + { 0x0600, 0x610794 }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nv94_disp_mast_mthd_chan = { + .name = "Core", + .addr = 0x000000, + .data = { + { "Global", 1, &nv50_disp_mast_mthd_base }, + { "DAC", 3, &nv84_disp_mast_mthd_dac }, + { "SOR", 4, &nv94_disp_mast_mthd_sor }, + { "PIOR", 3, &nv50_disp_mast_mthd_pior }, + { "HEAD", 2, &nv84_disp_mast_mthd_head }, + {} + } +}; + +/******************************************************************************* + * Base display object + ******************************************************************************/ + static struct nouveau_oclass nv94_disp_sclass[] = { { NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, @@ -45,6 +77,7 @@ nv94_disp_base_omthds[] = { { 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 }, @@ -59,6 +92,10 @@ nv94_disp_base_oclass[] = { {} }; +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + static int nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -86,19 +123,29 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->dac.sense = nv50_dac_sense; priv->sor.power = nv50_sor_power; priv->sor.hdmi = nv84_hdmi_ctrl; - priv->sor.dp = &nv94_sor_dp_func; priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; return 0; } -struct nouveau_oclass -nv94_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x88), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nv94_disp_outp_sclass[] = { + &nv50_pior_dp_impl.base.base, + &nv94_sor_dp_impl.base.base, + NULL +}; + +struct nouveau_oclass * +nv94_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x88), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv94_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 6cf8eefac36..6237a9a36f7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c @@ -29,6 +29,55 @@ #include "nv50.h" +/******************************************************************************* + * EVO overlay channel objects + ******************************************************************************/ + +static const struct nv50_disp_mthd_list +nva0_disp_ovly_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x000000 }, + { 0x0084, 0x6109a0 }, + { 0x0088, 0x6109c0 }, + { 0x008c, 0x6109c8 }, + { 0x0090, 0x6109b4 }, + { 0x0094, 0x610970 }, + { 0x00a0, 0x610998 }, + { 0x00a4, 0x610964 }, + { 0x00b0, 0x610c98 }, + { 0x00b4, 0x610ca4 }, + { 0x00b8, 0x610cac }, + { 0x00c0, 0x610958 }, + { 0x00e0, 0x6109a8 }, + { 0x00e4, 0x6109d0 }, + { 0x00e8, 0x6109d8 }, + { 0x0100, 0x61094c }, + { 0x0104, 0x610984 }, + { 0x0108, 0x61098c }, + { 0x0800, 0x6109f8 }, + { 0x0808, 0x610a08 }, + { 0x080c, 0x610a10 }, + { 0x0810, 0x610a00 }, + {} + } +}; + +static const struct nv50_disp_mthd_chan +nva0_disp_ovly_mthd_chan = { + .name = "Overlay", + .addr = 0x000540, + .data = { + { "Global", 1, &nva0_disp_ovly_mthd_base }, + {} + } +}; + +/******************************************************************************* + * Base display object + ******************************************************************************/ + static struct nouveau_oclass nva0_disp_sclass[] = { { NVA0_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, @@ -45,6 +94,10 @@ nva0_disp_base_oclass[] = { {} }; +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + static int nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -73,17 +126,21 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hdmi = nv84_hdmi_ctrl; priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; return 0; } -struct nouveau_oclass -nva0_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x83), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nva0_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x83), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nva0_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 6ad6dcece43..019124d4782 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c @@ -29,6 +29,10 @@ #include "nv50.h" +/******************************************************************************* + * Base display object + ******************************************************************************/ + static struct nouveau_oclass nva3_disp_sclass[] = { { NVA3_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs }, @@ -46,6 +50,7 @@ nva3_disp_base_omthds[] = { { 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 }, @@ -60,6 +65,10 @@ nva3_disp_base_oclass[] = { {} }; +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + static int nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -88,19 +97,22 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nva3_hda_eld; priv->sor.hdmi = nva3_hdmi_ctrl; - priv->sor.dp = &nv94_sor_dp_func; priv->pior.power = nv50_pior_power; - priv->pior.dp = &nv50_pior_dp_func; return 0; } -struct nouveau_oclass -nva3_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x85), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nva3_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x85), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nva3_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 1c5e4e8b2c8..fa30d8196f3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -124,6 +124,146 @@ nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend) * EVO master channel object ******************************************************************************/ +const struct nv50_disp_mthd_list +nvd0_disp_mast_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x660080 }, + { 0x0084, 0x660084 }, + { 0x0088, 0x660088 }, + { 0x008c, 0x000000 }, + {} + } +}; + +const struct nv50_disp_mthd_list +nvd0_disp_mast_mthd_dac = { + .mthd = 0x0020, + .addr = 0x000020, + .data = { + { 0x0180, 0x660180 }, + { 0x0184, 0x660184 }, + { 0x0188, 0x660188 }, + { 0x0190, 0x660190 }, + {} + } +}; + +const struct nv50_disp_mthd_list +nvd0_disp_mast_mthd_sor = { + .mthd = 0x0020, + .addr = 0x000020, + .data = { + { 0x0200, 0x660200 }, + { 0x0204, 0x660204 }, + { 0x0208, 0x660208 }, + { 0x0210, 0x660210 }, + {} + } +}; + +const struct nv50_disp_mthd_list +nvd0_disp_mast_mthd_pior = { + .mthd = 0x0020, + .addr = 0x000020, + .data = { + { 0x0300, 0x660300 }, + { 0x0304, 0x660304 }, + { 0x0308, 0x660308 }, + { 0x0310, 0x660310 }, + {} + } +}; + +static const struct nv50_disp_mthd_list +nvd0_disp_mast_mthd_head = { + .mthd = 0x0300, + .addr = 0x000300, + .data = { + { 0x0400, 0x660400 }, + { 0x0404, 0x660404 }, + { 0x0408, 0x660408 }, + { 0x040c, 0x66040c }, + { 0x0410, 0x660410 }, + { 0x0414, 0x660414 }, + { 0x0418, 0x660418 }, + { 0x041c, 0x66041c }, + { 0x0420, 0x660420 }, + { 0x0424, 0x660424 }, + { 0x0428, 0x660428 }, + { 0x042c, 0x66042c }, + { 0x0430, 0x660430 }, + { 0x0434, 0x660434 }, + { 0x0438, 0x660438 }, + { 0x0440, 0x660440 }, + { 0x0444, 0x660444 }, + { 0x0448, 0x660448 }, + { 0x044c, 0x66044c }, + { 0x0450, 0x660450 }, + { 0x0454, 0x660454 }, + { 0x0458, 0x660458 }, + { 0x045c, 0x66045c }, + { 0x0460, 0x660460 }, + { 0x0468, 0x660468 }, + { 0x046c, 0x66046c }, + { 0x0470, 0x660470 }, + { 0x0474, 0x660474 }, + { 0x0480, 0x660480 }, + { 0x0484, 0x660484 }, + { 0x048c, 0x66048c }, + { 0x0490, 0x660490 }, + { 0x0494, 0x660494 }, + { 0x0498, 0x660498 }, + { 0x04b0, 0x6604b0 }, + { 0x04b8, 0x6604b8 }, + { 0x04bc, 0x6604bc }, + { 0x04c0, 0x6604c0 }, + { 0x04c4, 0x6604c4 }, + { 0x04c8, 0x6604c8 }, + { 0x04d0, 0x6604d0 }, + { 0x04d4, 0x6604d4 }, + { 0x04e0, 0x6604e0 }, + { 0x04e4, 0x6604e4 }, + { 0x04e8, 0x6604e8 }, + { 0x04ec, 0x6604ec }, + { 0x04f0, 0x6604f0 }, + { 0x04f4, 0x6604f4 }, + { 0x04f8, 0x6604f8 }, + { 0x04fc, 0x6604fc }, + { 0x0500, 0x660500 }, + { 0x0504, 0x660504 }, + { 0x0508, 0x660508 }, + { 0x050c, 0x66050c }, + { 0x0510, 0x660510 }, + { 0x0514, 0x660514 }, + { 0x0518, 0x660518 }, + { 0x051c, 0x66051c }, + { 0x052c, 0x66052c }, + { 0x0530, 0x660530 }, + { 0x054c, 0x66054c }, + { 0x0550, 0x660550 }, + { 0x0554, 0x660554 }, + { 0x0558, 0x660558 }, + { 0x055c, 0x66055c }, + {} + } +}; + +static const struct nv50_disp_mthd_chan +nvd0_disp_mast_mthd_chan = { + .name = "Core", + .addr = 0x000000, + .data = { + { "Global", 1, &nvd0_disp_mast_mthd_base }, + { "DAC", 3, &nvd0_disp_mast_mthd_dac }, + { "SOR", 8, &nvd0_disp_mast_mthd_sor }, + { "PIOR", 4, &nvd0_disp_mast_mthd_pior }, + { "HEAD", 4, &nvd0_disp_mast_mthd_head }, + {} + } +}; + static int nvd0_disp_mast_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -216,6 +356,81 @@ nvd0_disp_mast_ofuncs = { * EVO sync channel objects ******************************************************************************/ +static const struct nv50_disp_mthd_list +nvd0_disp_sync_mthd_base = { + .mthd = 0x0000, + .addr = 0x000000, + .data = { + { 0x0080, 0x661080 }, + { 0x0084, 0x661084 }, + { 0x0088, 0x661088 }, + { 0x008c, 0x66108c }, + { 0x0090, 0x661090 }, + { 0x0094, 0x661094 }, + { 0x00a0, 0x6610a0 }, + { 0x00a4, 0x6610a4 }, + { 0x00c0, 0x6610c0 }, + { 0x00c4, 0x6610c4 }, + { 0x00c8, 0x6610c8 }, + { 0x00cc, 0x6610cc }, + { 0x00e0, 0x6610e0 }, + { 0x00e4, 0x6610e4 }, + { 0x00e8, 0x6610e8 }, + { 0x00ec, 0x6610ec }, + { 0x00fc, 0x6610fc }, + { 0x0100, 0x661100 }, + { 0x0104, 0x661104 }, + { 0x0108, 0x661108 }, + { 0x010c, 0x66110c }, + { 0x0110, 0x661110 }, + { 0x0114, 0x661114 }, + { 0x0118, 0x661118 }, + { 0x011c, 0x66111c }, + { 0x0130, 0x661130 }, + { 0x0134, 0x661134 }, + { 0x0138, 0x661138 }, + { 0x013c, 0x66113c }, + { 0x0140, 0x661140 }, + { 0x0144, 0x661144 }, + { 0x0148, 0x661148 }, + { 0x014c, 0x66114c }, + { 0x0150, 0x661150 }, + { 0x0154, 0x661154 }, + { 0x0158, 0x661158 }, + { 0x015c, 0x66115c }, + { 0x0160, 0x661160 }, + { 0x0164, 0x661164 }, + { 0x0168, 0x661168 }, + { 0x016c, 0x66116c }, + {} + } +}; + +static const struct nv50_disp_mthd_list +nvd0_disp_sync_mthd_image = { + .mthd = 0x0400, + .addr = 0x000400, + .data = { + { 0x0400, 0x661400 }, + { 0x0404, 0x661404 }, + { 0x0408, 0x661408 }, + { 0x040c, 0x66140c }, + { 0x0410, 0x661410 }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nvd0_disp_sync_mthd_chan = { + .name = "Base", + .addr = 0x001000, + .data = { + { "Global", 1, &nvd0_disp_sync_mthd_base }, + { "Image", 2, &nvd0_disp_sync_mthd_image }, + {} + } +}; + static int nvd0_disp_sync_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -256,6 +471,68 @@ nvd0_disp_sync_ofuncs = { * EVO overlay channel objects ******************************************************************************/ +static const struct nv50_disp_mthd_list +nvd0_disp_ovly_mthd_base = { + .mthd = 0x0000, + .data = { + { 0x0080, 0x665080 }, + { 0x0084, 0x665084 }, + { 0x0088, 0x665088 }, + { 0x008c, 0x66508c }, + { 0x0090, 0x665090 }, + { 0x0094, 0x665094 }, + { 0x00a0, 0x6650a0 }, + { 0x00a4, 0x6650a4 }, + { 0x00b0, 0x6650b0 }, + { 0x00b4, 0x6650b4 }, + { 0x00b8, 0x6650b8 }, + { 0x00c0, 0x6650c0 }, + { 0x00e0, 0x6650e0 }, + { 0x00e4, 0x6650e4 }, + { 0x00e8, 0x6650e8 }, + { 0x0100, 0x665100 }, + { 0x0104, 0x665104 }, + { 0x0108, 0x665108 }, + { 0x010c, 0x66510c }, + { 0x0110, 0x665110 }, + { 0x0118, 0x665118 }, + { 0x011c, 0x66511c }, + { 0x0120, 0x665120 }, + { 0x0124, 0x665124 }, + { 0x0130, 0x665130 }, + { 0x0134, 0x665134 }, + { 0x0138, 0x665138 }, + { 0x013c, 0x66513c }, + { 0x0140, 0x665140 }, + { 0x0144, 0x665144 }, + { 0x0148, 0x665148 }, + { 0x014c, 0x66514c }, + { 0x0150, 0x665150 }, + { 0x0154, 0x665154 }, + { 0x0158, 0x665158 }, + { 0x015c, 0x66515c }, + { 0x0160, 0x665160 }, + { 0x0164, 0x665164 }, + { 0x0168, 0x665168 }, + { 0x016c, 0x66516c }, + { 0x0400, 0x665400 }, + { 0x0408, 0x665408 }, + { 0x040c, 0x66540c }, + { 0x0410, 0x665410 }, + {} + } +}; + +static const struct nv50_disp_mthd_chan +nvd0_disp_ovly_mthd_chan = { + .name = "Overlay", + .addr = 0x001000, + .data = { + { "Global", 1, &nvd0_disp_ovly_mthd_base }, + {} + } +}; + static int nvd0_disp_ovly_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -471,13 +748,13 @@ nvd0_disp_base_scanoutpos(struct nouveau_object *object, u32 mthd, } static void -nvd0_disp_base_vblank_enable(struct nouveau_event *event, int head) +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 head) +nvd0_disp_base_vblank_disable(struct nouveau_event *event, int type, int head) { nv_mask(event->priv, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000); } @@ -610,6 +887,7 @@ nvd0_disp_base_omthds[] = { { 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 }, @@ -638,19 +916,20 @@ nvd0_disp_sclass[] = { * Display engine implementation ******************************************************************************/ -static u16 -exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, - struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, +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, struct nvbios_outp *info) { struct nouveau_bios *bios = nouveau_bios(priv); - u16 mask, type, data; + struct nvkm_output *outp; + u16 mask, type; - if (outp < 4) { + if (or < 4) { type = DCB_OUTPUT_ANALOG; mask = 0; } else { - outp -= 4; + or -= 4; switch (ctrl & 0x00000f00) { case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break; case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break; @@ -662,101 +941,106 @@ exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl); return 0x0000; } - dcb->sorconf.link = mask; } mask = 0x00c0 & (mask << 6); - mask |= 0x0001 << outp; + mask |= 0x0001 << or; mask |= 0x0100 << head; - data = dcb_outp_match(bios, type, mask, ver, hdr, dcb); - if (!data) - return 0x0000; + list_for_each_entry(outp, &priv->base.outp, head) { + if ((outp->info.hasht & 0xff) == type && + (outp->info.hashm & mask) == mask) { + *data = nvbios_outp_match(bios, outp->info.hasht, + outp->info.hashm, + ver, hdr, cnt, len, info); + if (!*data) + return NULL; + return outp; + } + } - return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info); + return NULL; } -static bool +static struct nvkm_output * exec_script(struct nv50_disp_priv *priv, int head, int id) { struct nouveau_bios *bios = nouveau_bios(priv); + struct nvkm_output *outp; struct nvbios_outp info; - struct dcb_output dcb; u8 ver, hdr, cnt, len; - u32 ctrl = 0x00000000; - u16 data; - int outp; + u32 data, ctrl = 0; + int or; - for (outp = 0; !(ctrl & (1 << head)) && outp < 8; outp++) { - ctrl = nv_rd32(priv, 0x640180 + (outp * 0x20)); + for (or = 0; !(ctrl & (1 << head)) && or < 8; or++) { + ctrl = nv_rd32(priv, 0x640180 + (or * 0x20)); if (ctrl & (1 << head)) break; } - if (outp == 8) - return false; + if (or == 8) + return NULL; - data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info); - if (data) { + outp = exec_lookup(priv, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info); + if (outp) { struct nvbios_init init = { .subdev = nv_subdev(priv), .bios = bios, .offset = info.script[id], - .outp = &dcb, + .outp = &outp->info, .crtc = head, .execute = 1, }; - return nvbios_exec(&init) == 0; + nvbios_exec(&init); } - return false; + return outp; } -static u32 -exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, - u32 pclk, struct dcb_output *dcb) +static struct nvkm_output * +exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 *conf) { struct nouveau_bios *bios = nouveau_bios(priv); + struct nvkm_output *outp; struct nvbios_outp info1; struct nvbios_ocfg info2; u8 ver, hdr, cnt, len; - u32 ctrl = 0x00000000; - u32 data, conf = ~0; - int outp; + u32 data, ctrl = 0; + int or; - for (outp = 0; !(ctrl & (1 << head)) && outp < 8; outp++) { - ctrl = nv_rd32(priv, 0x660180 + (outp * 0x20)); + for (or = 0; !(ctrl & (1 << head)) && or < 8; or++) { + ctrl = nv_rd32(priv, 0x660180 + (or * 0x20)); if (ctrl & (1 << head)) break; } - if (outp == 8) - return false; + if (or == 8) + return NULL; - data = exec_lookup(priv, head, outp, ctrl, dcb, &ver, &hdr, &cnt, &len, &info1); - if (data == 0x0000) - return conf; + outp = exec_lookup(priv, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info1); + if (!outp) + return NULL; - switch (dcb->type) { + switch (outp->info.type) { case DCB_OUTPUT_TMDS: - conf = (ctrl & 0x00000f00) >> 8; + *conf = (ctrl & 0x00000f00) >> 8; if (pclk >= 165000) - conf |= 0x0100; + *conf |= 0x0100; break; case DCB_OUTPUT_LVDS: - conf = priv->sor.lvdsconf; + *conf = priv->sor.lvdsconf; break; case DCB_OUTPUT_DP: - conf = (ctrl & 0x00000f00) >> 8; + *conf = (ctrl & 0x00000f00) >> 8; break; case DCB_OUTPUT_ANALOG: default: - conf = 0x00ff; + *conf = 0x00ff; break; } - data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2); + data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2); if (data && id < 0xff) { data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); if (data) { @@ -764,7 +1048,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, .subdev = nv_subdev(priv), .bios = bios, .offset = data, - .outp = dcb, + .outp = &outp->info, .crtc = head, .execute = 1, }; @@ -773,7 +1057,7 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, } } - return conf; + return outp; } static void @@ -785,7 +1069,23 @@ nvd0_disp_intr_unk1_0(struct nv50_disp_priv *priv, int head) static void nvd0_disp_intr_unk2_0(struct nv50_disp_priv *priv, int head) { - exec_script(priv, head, 2); + struct nvkm_output *outp = exec_script(priv, head, 2); + + /* see note in nv50_disp_intr_unk20_0() */ + if (outp && outp->info.type == DCB_OUTPUT_DP) { + struct nvkm_output_dp *outpdp = (void *)outp; + struct nvbios_init init = { + .subdev = nv_subdev(priv), + .bios = nouveau_bios(priv), + .outp = &outp->info, + .crtc = head, + .offset = outpdp->info.script[4], + .execute = 1, + }; + + nvbios_exec(&init); + atomic_set(&outpdp->lt.done, 0); + } } static void @@ -847,49 +1147,52 @@ nvd0_disp_intr_unk2_2_tu(struct nv50_disp_priv *priv, int head, static void nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head) { - struct dcb_output outp; + struct nvkm_output *outp; u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; - u32 conf = exec_clkcmp(priv, head, 0xff, pclk, &outp); - if (conf != ~0) { - u32 addr, data; - - if (outp.type == DCB_OUTPUT_DP) { - u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); - switch ((sync & 0x000003c0) >> 6) { - case 6: pclk = pclk * 30 / 8; break; - case 5: pclk = pclk * 24 / 8; break; - case 2: - default: - pclk = pclk * 18 / 8; - break; - } - - nouveau_dp_train(&priv->base, priv->sor.dp, - &outp, head, pclk); + u32 conf, addr, data; + + outp = exec_clkcmp(priv, head, 0xff, pclk, &conf); + if (!outp) + return; + + /* see note in nv50_disp_intr_unk20_2() */ + if (outp->info.type == DCB_OUTPUT_DP) { + u32 sync = nv_rd32(priv, 0x660404 + (head * 0x300)); + switch ((sync & 0x000003c0) >> 6) { + case 6: pclk = pclk * 30; break; + case 5: pclk = pclk * 24; break; + case 2: + default: + pclk = pclk * 18; + break; } - exec_clkcmp(priv, head, 0, pclk, &outp); + if (nvkm_output_dp_train(outp, pclk, true)) + ERR("link not trained before attach\n"); + } - if (outp.type == DCB_OUTPUT_ANALOG) { - addr = 0x612280 + (ffs(outp.or) - 1) * 0x800; - data = 0x00000000; - } else { - if (outp.type == DCB_OUTPUT_DP) - nvd0_disp_intr_unk2_2_tu(priv, head, &outp); - addr = 0x612300 + (ffs(outp.or) - 1) * 0x800; - data = (conf & 0x0100) ? 0x00000101 : 0x00000000; - } + exec_clkcmp(priv, head, 0, pclk, &conf); - nv_mask(priv, addr, 0x00000707, data); + if (outp->info.type == DCB_OUTPUT_ANALOG) { + addr = 0x612280 + (ffs(outp->info.or) - 1) * 0x800; + data = 0x00000000; + } else { + if (outp->info.type == DCB_OUTPUT_DP) + nvd0_disp_intr_unk2_2_tu(priv, head, &outp->info); + addr = 0x612300 + (ffs(outp->info.or) - 1) * 0x800; + data = (conf & 0x0100) ? 0x00000101 : 0x00000000; } + + nv_mask(priv, addr, 0x00000707, data); } static void nvd0_disp_intr_unk4_0(struct nv50_disp_priv *priv, int head) { - struct dcb_output outp; u32 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000; - exec_clkcmp(priv, head, 1, pclk, &outp); + u32 conf; + + exec_clkcmp(priv, head, 1, pclk, &conf); } void @@ -897,19 +1200,22 @@ nvd0_disp_intr_supervisor(struct work_struct *work) { struct nv50_disp_priv *priv = container_of(work, struct nv50_disp_priv, supervisor); + struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass; u32 mask[4]; int head; - nv_debug(priv, "supervisor %08x\n", priv->super); + nv_debug(priv, "supervisor %d\n", ffs(priv->super)); for (head = 0; head < priv->head.nr; head++) { mask[head] = nv_rd32(priv, 0x6101d4 + (head * 0x800)); nv_debug(priv, "head %d: 0x%08x\n", head, mask[head]); } if (priv->super & 0x00000001) { + nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core); for (head = 0; head < priv->head.nr; head++) { if (!(mask[head] & 0x00001000)) continue; + nv_debug(priv, "supervisor 1.0 - head %d\n", head); nvd0_disp_intr_unk1_0(priv, head); } } else @@ -917,16 +1223,19 @@ nvd0_disp_intr_supervisor(struct work_struct *work) for (head = 0; head < priv->head.nr; head++) { if (!(mask[head] & 0x00001000)) continue; + nv_debug(priv, "supervisor 2.0 - head %d\n", head); nvd0_disp_intr_unk2_0(priv, head); } for (head = 0; head < priv->head.nr; head++) { if (!(mask[head] & 0x00010000)) continue; + nv_debug(priv, "supervisor 2.1 - head %d\n", head); nvd0_disp_intr_unk2_1(priv, head); } for (head = 0; head < priv->head.nr; head++) { if (!(mask[head] & 0x00001000)) continue; + nv_debug(priv, "supervisor 2.2 - head %d\n", head); nvd0_disp_intr_unk2_2(priv, head); } } else @@ -934,6 +1243,7 @@ nvd0_disp_intr_supervisor(struct work_struct *work) for (head = 0; head < priv->head.nr; head++) { if (!(mask[head] & 0x00001000)) continue; + nv_debug(priv, "supervisor 3.0 - head %d\n", head); nvd0_disp_intr_unk4_0(priv, head); } } @@ -943,6 +1253,53 @@ nvd0_disp_intr_supervisor(struct work_struct *work) nv_wr32(priv, 0x6101d0, 0x80000000); } +static void +nvd0_disp_intr_error(struct nv50_disp_priv *priv, int chid) +{ + const struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass; + u32 mthd = nv_rd32(priv, 0x6101f0 + (chid * 12)); + u32 data = nv_rd32(priv, 0x6101f4 + (chid * 12)); + u32 unkn = nv_rd32(priv, 0x6101f8 + (chid * 12)); + + nv_error(priv, "chid %d mthd 0x%04x data 0x%08x " + "0x%08x 0x%08x\n", + chid, (mthd & 0x0000ffc), data, mthd, unkn); + + if (chid == 0) { + switch (mthd & 0xffc) { + case 0x0080: + nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0, + impl->mthd.core); + break; + default: + break; + } + } else + if (chid <= 4) { + switch (mthd & 0xffc) { + case 0x0080: + nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1, + impl->mthd.base); + break; + default: + break; + } + } else + if (chid <= 8) { + switch (mthd & 0xffc) { + case 0x0080: + nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 5, + impl->mthd.ovly); + break; + default: + break; + } + } + + nv_wr32(priv, 0x61009c, (1 << chid)); + nv_wr32(priv, 0x6101f0 + (chid * 12), 0x90000000); +} + void nvd0_disp_intr(struct nouveau_subdev *subdev) { @@ -959,18 +1316,8 @@ nvd0_disp_intr(struct nouveau_subdev *subdev) if (intr & 0x00000002) { u32 stat = nv_rd32(priv, 0x61009c); int chid = ffs(stat) - 1; - if (chid >= 0) { - u32 mthd = nv_rd32(priv, 0x6101f0 + (chid * 12)); - u32 data = nv_rd32(priv, 0x6101f4 + (chid * 12)); - u32 unkn = nv_rd32(priv, 0x6101f8 + (chid * 12)); - - nv_error(priv, "chid %d mthd 0x%04x data 0x%08x " - "0x%08x 0x%08x\n", - chid, (mthd & 0x0000ffc), data, mthd, unkn); - nv_wr32(priv, 0x61009c, (1 << chid)); - nv_wr32(priv, 0x6101f0 + (chid * 12), 0x90000000); - } - + if (chid >= 0) + nvd0_disp_intr_error(priv, chid); intr &= ~0x00000002; } @@ -996,7 +1343,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, i); + nouveau_event_trigger(priv->base.vblank, 1, i); nv_mask(priv, 0x6100bc + (i * 0x800), 0, 0); nv_rd32(priv, 0x6100c0 + (i * 0x800)); } @@ -1031,17 +1378,27 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nvd0_hda_eld; priv->sor.hdmi = nvd0_hdmi_ctrl; - priv->sor.dp = &nvd0_sor_dp_func; return 0; } -struct nouveau_oclass -nvd0_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x90), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nvd0_disp_outp_sclass[] = { + &nvd0_sor_dp_impl.base.base, + NULL +}; + +struct nouveau_oclass * +nvd0_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x90), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nvd0_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 ab63f32c00b..11328e3f5df 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c @@ -29,6 +29,175 @@ #include "nv50.h" +/******************************************************************************* + * EVO master channel object + ******************************************************************************/ + +static const struct nv50_disp_mthd_list +nve0_disp_mast_mthd_head = { + .mthd = 0x0300, + .addr = 0x000300, + .data = { + { 0x0400, 0x660400 }, + { 0x0404, 0x660404 }, + { 0x0408, 0x660408 }, + { 0x040c, 0x66040c }, + { 0x0410, 0x660410 }, + { 0x0414, 0x660414 }, + { 0x0418, 0x660418 }, + { 0x041c, 0x66041c }, + { 0x0420, 0x660420 }, + { 0x0424, 0x660424 }, + { 0x0428, 0x660428 }, + { 0x042c, 0x66042c }, + { 0x0430, 0x660430 }, + { 0x0434, 0x660434 }, + { 0x0438, 0x660438 }, + { 0x0440, 0x660440 }, + { 0x0444, 0x660444 }, + { 0x0448, 0x660448 }, + { 0x044c, 0x66044c }, + { 0x0450, 0x660450 }, + { 0x0454, 0x660454 }, + { 0x0458, 0x660458 }, + { 0x045c, 0x66045c }, + { 0x0460, 0x660460 }, + { 0x0468, 0x660468 }, + { 0x046c, 0x66046c }, + { 0x0470, 0x660470 }, + { 0x0474, 0x660474 }, + { 0x047c, 0x66047c }, + { 0x0480, 0x660480 }, + { 0x0484, 0x660484 }, + { 0x0488, 0x660488 }, + { 0x048c, 0x66048c }, + { 0x0490, 0x660490 }, + { 0x0494, 0x660494 }, + { 0x0498, 0x660498 }, + { 0x04a0, 0x6604a0 }, + { 0x04b0, 0x6604b0 }, + { 0x04b8, 0x6604b8 }, + { 0x04bc, 0x6604bc }, + { 0x04c0, 0x6604c0 }, + { 0x04c4, 0x6604c4 }, + { 0x04c8, 0x6604c8 }, + { 0x04d0, 0x6604d0 }, + { 0x04d4, 0x6604d4 }, + { 0x04e0, 0x6604e0 }, + { 0x04e4, 0x6604e4 }, + { 0x04e8, 0x6604e8 }, + { 0x04ec, 0x6604ec }, + { 0x04f0, 0x6604f0 }, + { 0x04f4, 0x6604f4 }, + { 0x04f8, 0x6604f8 }, + { 0x04fc, 0x6604fc }, + { 0x0500, 0x660500 }, + { 0x0504, 0x660504 }, + { 0x0508, 0x660508 }, + { 0x050c, 0x66050c }, + { 0x0510, 0x660510 }, + { 0x0514, 0x660514 }, + { 0x0518, 0x660518 }, + { 0x051c, 0x66051c }, + { 0x0520, 0x660520 }, + { 0x0524, 0x660524 }, + { 0x052c, 0x66052c }, + { 0x0530, 0x660530 }, + { 0x054c, 0x66054c }, + { 0x0550, 0x660550 }, + { 0x0554, 0x660554 }, + { 0x0558, 0x660558 }, + { 0x055c, 0x66055c }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nve0_disp_mast_mthd_chan = { + .name = "Core", + .addr = 0x000000, + .data = { + { "Global", 1, &nvd0_disp_mast_mthd_base }, + { "DAC", 3, &nvd0_disp_mast_mthd_dac }, + { "SOR", 8, &nvd0_disp_mast_mthd_sor }, + { "PIOR", 4, &nvd0_disp_mast_mthd_pior }, + { "HEAD", 4, &nve0_disp_mast_mthd_head }, + {} + } +}; + +/******************************************************************************* + * EVO overlay channel objects + ******************************************************************************/ + +static const struct nv50_disp_mthd_list +nve0_disp_ovly_mthd_base = { + .mthd = 0x0000, + .data = { + { 0x0080, 0x665080 }, + { 0x0084, 0x665084 }, + { 0x0088, 0x665088 }, + { 0x008c, 0x66508c }, + { 0x0090, 0x665090 }, + { 0x0094, 0x665094 }, + { 0x00a0, 0x6650a0 }, + { 0x00a4, 0x6650a4 }, + { 0x00b0, 0x6650b0 }, + { 0x00b4, 0x6650b4 }, + { 0x00b8, 0x6650b8 }, + { 0x00c0, 0x6650c0 }, + { 0x00c4, 0x6650c4 }, + { 0x00e0, 0x6650e0 }, + { 0x00e4, 0x6650e4 }, + { 0x00e8, 0x6650e8 }, + { 0x0100, 0x665100 }, + { 0x0104, 0x665104 }, + { 0x0108, 0x665108 }, + { 0x010c, 0x66510c }, + { 0x0110, 0x665110 }, + { 0x0118, 0x665118 }, + { 0x011c, 0x66511c }, + { 0x0120, 0x665120 }, + { 0x0124, 0x665124 }, + { 0x0130, 0x665130 }, + { 0x0134, 0x665134 }, + { 0x0138, 0x665138 }, + { 0x013c, 0x66513c }, + { 0x0140, 0x665140 }, + { 0x0144, 0x665144 }, + { 0x0148, 0x665148 }, + { 0x014c, 0x66514c }, + { 0x0150, 0x665150 }, + { 0x0154, 0x665154 }, + { 0x0158, 0x665158 }, + { 0x015c, 0x66515c }, + { 0x0160, 0x665160 }, + { 0x0164, 0x665164 }, + { 0x0168, 0x665168 }, + { 0x016c, 0x66516c }, + { 0x0400, 0x665400 }, + { 0x0404, 0x665404 }, + { 0x0408, 0x665408 }, + { 0x040c, 0x66540c }, + { 0x0410, 0x665410 }, + {} + } +}; + +const struct nv50_disp_mthd_chan +nve0_disp_ovly_mthd_chan = { + .name = "Overlay", + .addr = 0x001000, + .data = { + { "Global", 1, &nve0_disp_ovly_mthd_base }, + {} + } +}; + +/******************************************************************************* + * Base display object + ******************************************************************************/ + static struct nouveau_oclass nve0_disp_sclass[] = { { NVE0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs }, @@ -45,6 +214,10 @@ nve0_disp_base_oclass[] = { {} }; +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + static int nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -73,17 +246,21 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nvd0_hda_eld; priv->sor.hdmi = nvd0_hdmi_ctrl; - priv->sor.dp = &nvd0_sor_dp_func; return 0; } -struct nouveau_oclass -nve0_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x91), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nve0_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x91), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nve0_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.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 05fee10e0c9..104388081d7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c @@ -29,6 +29,10 @@ #include "nv50.h" +/******************************************************************************* + * Base display object + ******************************************************************************/ + static struct nouveau_oclass nvf0_disp_sclass[] = { { NVF0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs }, @@ -45,6 +49,10 @@ nvf0_disp_base_oclass[] = { {} }; +/******************************************************************************* + * Display engine implementation + ******************************************************************************/ + static int nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -73,17 +81,21 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->sor.power = nv50_sor_power; priv->sor.hda_eld = nvd0_hda_eld; priv->sor.hdmi = nvd0_hdmi_ctrl; - priv->sor.dp = &nvd0_sor_dp_func; return 0; } -struct nouveau_oclass -nvf0_disp_oclass = { - .handle = NV_ENGINE(DISP, 0x92), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nvf0_disp_oclass = &(struct nv50_disp_impl) { + .base.base.handle = NV_ENGINE(DISP, 0x92), + .base.base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nvf0_disp_ctor, .dtor = _nouveau_disp_dtor, .init = _nouveau_disp_init, .fini = _nouveau_disp_fini, }, -}; + .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, +}.base.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outp.c new file mode 100644 index 00000000000..ad9ba7ccec7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outp.c @@ -0,0 +1,137 @@ +/* + * 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 <subdev/i2c.h> +#include <subdev/bios.h> +#include <subdev/bios/conn.h> + +#include "outp.h" + +int +_nvkm_output_fini(struct nouveau_object *object, bool suspend) +{ + struct nvkm_output *outp = (void *)object; + nv_ofuncs(outp->conn)->fini(nv_object(outp->conn), suspend); + return nouveau_object_fini(&outp->base, suspend); +} + +int +_nvkm_output_init(struct nouveau_object *object) +{ + struct nvkm_output *outp = (void *)object; + int ret = nouveau_object_init(&outp->base); + if (ret == 0) + nv_ofuncs(outp->conn)->init(nv_object(outp->conn)); + return 0; +} + +void +_nvkm_output_dtor(struct nouveau_object *object) +{ + struct nvkm_output *outp = (void *)object; + list_del(&outp->head); + nouveau_object_ref(NULL, (void *)&outp->conn); + nouveau_object_destroy(&outp->base); +} + +int +nvkm_output_create_(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, + struct dcb_output *dcbE, int index, + int length, void **pobject) +{ + struct nouveau_bios *bios = nouveau_bios(engine); + struct nouveau_i2c *i2c = nouveau_i2c(parent); + struct nouveau_disp *disp = (void *)engine; + struct nvbios_connE connE; + struct nvkm_output *outp; + u8 ver, hdr; + u32 data; + int ret; + + ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject); + outp = *pobject; + if (ret) + return ret; + + outp->info = *dcbE; + outp->index = index; + + 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 ? + dcbE->sorconf.link : 0, dcbE->connector, dcbE->i2c_index, + dcbE->bus, dcbE->heads); + + outp->port = i2c->find(i2c, outp->info.i2c_index); + outp->edid = outp->port; + + data = nvbios_connEp(bios, outp->info.connector, &ver, &hdr, &connE); + if (!data) { + DBG("vbios connector data not found\n"); + memset(&connE, 0x00, sizeof(connE)); + connE.type = DCB_CONNECTOR_NONE; + } + + ret = nouveau_object_ctor(parent, engine, nvkm_connector_oclass, + &connE, outp->info.connector, + (struct nouveau_object **)&outp->conn); + if (ret < 0) { + ERR("error %d creating connector, disabling\n", ret); + return ret; + } + + list_add_tail(&outp->head, &disp->outp); + return 0; +} + +int +_nvkm_output_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *dcbE, u32 index, + struct nouveau_object **pobject) +{ + struct nvkm_output *outp; + int ret; + + ret = nvkm_output_create(parent, engine, oclass, dcbE, index, &outp); + *pobject = nv_object(outp); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass * +nvkm_output_oclass = &(struct nvkm_output_impl) { + .base = { + .handle = 0, + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_output_ctor, + .dtor = _nvkm_output_dtor, + .init = _nvkm_output_init, + .fini = _nvkm_output_fini, + }, + }, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.h b/drivers/gpu/drm/nouveau/core/engine/disp/outp.h new file mode 100644 index 00000000000..bc76fbf8571 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outp.h @@ -0,0 +1,59 @@ +#ifndef __NVKM_DISP_OUTP_H__ +#define __NVKM_DISP_OUTP_H__ + +#include "priv.h" + +struct nvkm_output { + struct nouveau_object base; + struct list_head head; + + struct dcb_output info; + int index; + + struct nouveau_i2c_port *port; + struct nouveau_i2c_port *edid; + + struct nvkm_connector *conn; +}; + +#define nvkm_output_create(p,e,c,b,i,d) \ + nvkm_output_create_((p), (e), (c), (b), (i), sizeof(**d), (void **)d) +#define nvkm_output_destroy(d) ({ \ + struct nvkm_output *_outp = (d); \ + _nvkm_output_dtor(nv_object(_outp)); \ +}) +#define nvkm_output_init(d) ({ \ + struct nvkm_output *_outp = (d); \ + _nvkm_output_init(nv_object(_outp)); \ +}) +#define nvkm_output_fini(d,s) ({ \ + struct nvkm_output *_outp = (d); \ + _nvkm_output_fini(nv_object(_outp), (s)); \ +}) + +int nvkm_output_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, struct dcb_output *, + int, int, void **); + +int _nvkm_output_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void _nvkm_output_dtor(struct nouveau_object *); +int _nvkm_output_init(struct nouveau_object *); +int _nvkm_output_fini(struct nouveau_object *, bool); + +struct nvkm_output_impl { + struct nouveau_oclass base; +}; + +#ifndef MSG +#define MSG(l,f,a...) do { \ + struct nvkm_output *_outp = (void *)outp; \ + nv_##l(nv_object(outp)->engine, "%02x:%04x:%04x: "f, _outp->index, \ + _outp->info.hasht, _outp->info.hashm, ##a); \ +} while(0) +#define DBG(f,a...) MSG(debug, f, ##a) +#define ERR(f,a...) MSG(error, f, ##a) +#endif + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c new file mode 100644 index 00000000000..eb2d7789555 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.c @@ -0,0 +1,278 @@ +/* + * 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 <subdev/i2c.h> + +#include "outpdp.h" +#include "conn.h" +#include "dport.h" + +int +nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) +{ + struct nvkm_output_dp *outp = (void *)base; + bool retrain = true; + u8 link[2], stat[3]; + u32 linkrate; + int ret, i; + + /* check that the link is trained at a high enough rate */ + ret = nv_rdaux(outp->base.edid, DPCD_LC00_LINK_BW_SET, link, 2); + if (ret) { + DBG("failed to read link config, assuming no sink\n"); + goto done; + } + + linkrate = link[0] * 27000 * (link[1] & DPCD_LC01_LANE_COUNT_SET); + linkrate = (linkrate * 8) / 10; /* 8B/10B coding overhead */ + datarate = (datarate + 9) / 10; /* -> decakilobits */ + if (linkrate < datarate) { + DBG("link not trained at sufficient rate\n"); + goto done; + } + + /* check that link is still trained */ + ret = nv_rdaux(outp->base.edid, DPCD_LS02, stat, 3); + if (ret) { + DBG("failed to read link status, assuming no sink\n"); + goto done; + } + + if (stat[2] & DPCD_LS04_INTERLANE_ALIGN_DONE) { + for (i = 0; i < (link[1] & DPCD_LC01_LANE_COUNT_SET); i++) { + u8 lane = (stat[i >> 1] >> ((i & 1) * 4)) & 0x0f; + if (!(lane & DPCD_LS02_LANE0_CR_DONE) || + !(lane & DPCD_LS02_LANE0_CHANNEL_EQ_DONE) || + !(lane & DPCD_LS02_LANE0_SYMBOL_LOCKED)) { + DBG("lane %d not equalised\n", lane); + goto done; + } + } + retrain = false; + } else { + DBG("no inter-lane alignment\n"); + } + +done: + if (retrain || !atomic_read(&outp->lt.done)) { + /* no sink, but still need to configure source */ + if (outp->dpcd[DPCD_RC00_DPCD_REV] == 0x00) { + outp->dpcd[DPCD_RC01_MAX_LINK_RATE] = + outp->base.info.dpconf.link_bw; + outp->dpcd[DPCD_RC02] = + outp->base.info.dpconf.link_nr; + } + atomic_set(&outp->lt.done, 0); + schedule_work(&outp->lt.work); + } else { + nouveau_event_get(outp->irq); + } + + if (wait) { + if (!wait_event_timeout(outp->lt.wait, + atomic_read(&outp->lt.done), + msecs_to_jiffies(2000))) + ret = -ETIMEDOUT; + } + + return ret; +} + +static void +nvkm_output_dp_enable(struct nvkm_output_dp *outp, bool present) +{ + struct nouveau_i2c_port *port = outp->base.edid; + if (present) { + if (!outp->present) { + nouveau_i2c(port)->acquire_pad(port, 0); + DBG("aux power -> always\n"); + outp->present = true; + } + nvkm_output_dp_train(&outp->base, 0, true); + } else { + if (outp->present) { + nouveau_i2c(port)->release_pad(port); + DBG("aux power -> demand\n"); + outp->present = false; + } + atomic_set(&outp->lt.done, 0); + } +} + +static void +nvkm_output_dp_detect(struct nvkm_output_dp *outp) +{ + struct nouveau_i2c_port *port = outp->base.edid; + int ret = nouveau_i2c(port)->acquire_pad(port, 0); + if (ret == 0) { + ret = nv_rdaux(outp->base.edid, DPCD_RC00_DPCD_REV, + outp->dpcd, sizeof(outp->dpcd)); + nvkm_output_dp_enable(outp, ret == 0); + nouveau_i2c(port)->release_pad(port); + } +} + +static void +nvkm_output_dp_service_work(struct work_struct *work) +{ + 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; + } + + nouveau_event_trigger(disp->hpd, send, outp->base.info.connector); +} + +static int +nvkm_output_dp_service(void *data, u32 type, int index) +{ + struct nvkm_output_dp *outp = data; + DBG("HPD: %d\n", type); + atomic_or(type, &outp->pending); + schedule_work(&outp->work); + return NVKM_EVENT_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_output_dp_enable(outp, false); + return nvkm_output_fini(&outp->base, suspend); +} + +int +_nvkm_output_dp_init(struct nouveau_object *object) +{ + struct nvkm_output_dp *outp = (void *)object; + nvkm_output_dp_detect(outp); + return nvkm_output_init(&outp->base); +} + +void +_nvkm_output_dp_dtor(struct nouveau_object *object) +{ + struct nvkm_output_dp *outp = (void *)object; + nouveau_event_ref(NULL, &outp->irq); + nvkm_output_destroy(&outp->base); +} + +int +nvkm_output_dp_create_(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, + struct dcb_output *info, int index, + int length, void **pobject) +{ + struct nouveau_bios *bios = nouveau_bios(parent); + struct nouveau_i2c *i2c = nouveau_i2c(parent); + struct nvkm_output_dp *outp; + u8 hdr, cnt, len; + u32 data; + int ret; + + ret = nvkm_output_create_(parent, engine, oclass, info, index, + length, pobject); + outp = *pobject; + if (ret) + return ret; + + nouveau_event_ref(NULL, &outp->base.conn->hpd.event); + + /* access to the aux channel is not optional... */ + if (!outp->base.edid) { + ERR("aux channel not found\n"); + return -ENODEV; + } + + /* nor is the bios data for this output... */ + data = nvbios_dpout_match(bios, outp->base.info.hasht, + outp->base.info.hashm, &outp->version, + &hdr, &cnt, &len, &outp->info); + if (!data) { + ERR("no bios dp data\n"); + return -ENODEV; + } + + DBG("bios dp %02x %02x %02x %02x\n", outp->version, hdr, cnt, len); + + /* link training */ + INIT_WORK(&outp->lt.work, nouveau_dp_train); + init_waitqueue_head(&outp->lt.wait); + 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); + 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); + if (ret) { + ERR("error monitoring aux hpd events: %d\n", ret); + return ret; + } + + return 0; +} + +int +_nvkm_output_dp_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *info, u32 index, + struct nouveau_object **pobject) +{ + struct nvkm_output_dp *outp; + int ret; + + ret = nvkm_output_dp_create(parent, engine, oclass, info, index, &outp); + *pobject = nv_object(outp); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h new file mode 100644 index 00000000000..ff33ba12cb6 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/outpdp.h @@ -0,0 +1,65 @@ +#ifndef __NVKM_DISP_OUTP_DP_H__ +#define __NVKM_DISP_OUTP_DP_H__ + +#include <subdev/bios.h> +#include <subdev/bios/dp.h> + +#include "outp.h" + +struct nvkm_output_dp { + struct nvkm_output base; + + struct nvbios_dpout info; + u8 version; + + struct nouveau_eventh *irq; + struct nouveau_eventh *hpd; + struct work_struct work; + atomic_t pending; + bool present; + u8 dpcd[16]; + + struct { + struct work_struct work; + wait_queue_head_t wait; + atomic_t done; + } lt; +}; + +#define nvkm_output_dp_create(p,e,c,b,i,d) \ + nvkm_output_dp_create_((p), (e), (c), (b), (i), sizeof(**d), (void **)d) +#define nvkm_output_dp_destroy(d) ({ \ + struct nvkm_output_dp *_outp = (d); \ + _nvkm_output_dp_dtor(nv_object(_outp)); \ +}) +#define nvkm_output_dp_init(d) ({ \ + struct nvkm_output_dp *_outp = (d); \ + _nvkm_output_dp_init(nv_object(_outp)); \ +}) +#define nvkm_output_dp_fini(d,s) ({ \ + struct nvkm_output_dp *_outp = (d); \ + _nvkm_output_dp_fini(nv_object(_outp), (s)); \ +}) + +int nvkm_output_dp_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, struct dcb_output *, + int, int, void **); + +int _nvkm_output_dp_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void _nvkm_output_dp_dtor(struct nouveau_object *); +int _nvkm_output_dp_init(struct nouveau_object *); +int _nvkm_output_dp_fini(struct nouveau_object *, bool); + +struct nvkm_output_dp_impl { + struct nvkm_output_impl base; + int (*pattern)(struct nvkm_output_dp *, int); + int (*lnk_pwr)(struct nvkm_output_dp *, int nr); + int (*lnk_ctl)(struct nvkm_output_dp *, int nr, int bw, bool ef); + int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc); +}; + +int nvkm_output_dp_train(struct nvkm_output *, u32 rate, bool wait); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c index 2c8ce351b52..fe0f256f11b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/piornv50.c @@ -33,68 +33,107 @@ #include "nv50.h" /****************************************************************************** - * DisplayPort + * TMDS *****************************************************************************/ -static struct nouveau_i2c_port * -nv50_pior_dp_find(struct nouveau_disp *disp, struct dcb_output *outp) + +static int +nv50_pior_tmds_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *info, u32 index, + struct nouveau_object **pobject) { - struct nouveau_i2c *i2c = nouveau_i2c(disp); - return i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(outp->extdev)); + struct nouveau_i2c *i2c = nouveau_i2c(parent); + struct nvkm_output *outp; + int ret; + + ret = nvkm_output_create(parent, engine, oclass, info, index, &outp); + *pobject = nv_object(outp); + if (ret) + return ret; + + outp->edid = i2c->find_type(i2c, NV_I2C_TYPE_EXTDDC(outp->info.extdev)); + return 0; } +struct nvkm_output_impl +nv50_pior_tmds_impl = { + .base.handle = DCB_OUTPUT_TMDS | 0x0100, + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_pior_tmds_ctor, + .dtor = _nvkm_output_dtor, + .init = _nvkm_output_init, + .fini = _nvkm_output_fini, + }, +}; + +/****************************************************************************** + * DisplayPort + *****************************************************************************/ + static int -nv50_pior_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int pattern) +nv50_pior_dp_pattern(struct nvkm_output_dp *outp, int pattern) { - struct nouveau_i2c_port *port; - int ret = -EINVAL; - - port = nv50_pior_dp_find(disp, outp); - if (port) { - if (port->func->pattern) - ret = port->func->pattern(port, pattern); - else - ret = 0; - } - - return ret; + struct nouveau_i2c_port *port = outp->base.edid; + if (port && port->func->pattern) + return port->func->pattern(port, pattern); + return port ? 0 : -ENODEV; } static int -nv50_pior_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane_nr, int link_bw, bool enh) +nv50_pior_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) { - struct nouveau_i2c_port *port; - int ret = -EINVAL; + return 0; +} - port = nv50_pior_dp_find(disp, outp); +static int +nv50_pior_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) +{ + struct nouveau_i2c_port *port = outp->base.edid; if (port && port->func->lnk_ctl) - ret = port->func->lnk_ctl(port, lane_nr, link_bw, enh); + return port->func->lnk_ctl(port, nr, bw, ef); + return port ? 0 : -ENODEV; +} - return ret; +static int +nv50_pior_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) +{ + struct nouveau_i2c_port *port = outp->base.edid; + if (port && port->func->drv_ctl) + return port->func->drv_ctl(port, ln, vs, pe); + return port ? 0 : -ENODEV; } static int -nv50_pior_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane, int vsw, int pre) +nv50_pior_dp_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *info, u32 index, + struct nouveau_object **pobject) { - struct nouveau_i2c_port *port; - int ret = -EINVAL; - - port = nv50_pior_dp_find(disp, outp); - if (port) { - if (port->func->drv_ctl) - ret = port->func->drv_ctl(port, lane, vsw, pre); - else - ret = 0; - } + struct nouveau_i2c *i2c = nouveau_i2c(parent); + struct nvkm_output_dp *outp; + int ret; - return ret; + ret = nvkm_output_dp_create(parent, engine, oclass, info, index, &outp); + *pobject = nv_object(outp); + if (ret) + return ret; + + outp->base.edid = i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX( + outp->base.info.extdev)); + return 0; } -const struct nouveau_dp_func -nv50_pior_dp_func = { +struct nvkm_output_dp_impl +nv50_pior_dp_impl = { + .base.base.handle = DCB_OUTPUT_DP | 0x0010, + .base.base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_pior_dp_ctor, + .dtor = _nvkm_output_dp_dtor, + .init = _nvkm_output_dp_init, + .fini = _nvkm_output_dp_fini, + }, .pattern = nv50_pior_dp_pattern, + .lnk_pwr = nv50_pior_dp_lnk_pwr, .lnk_ctl = nv50_pior_dp_lnk_ctl, .drv_ctl = nv50_pior_dp_drv_ctl, }; @@ -102,6 +141,7 @@ nv50_pior_dp_func = { /****************************************************************************** * General PIOR handling *****************************************************************************/ + int nv50_pior_power(struct nv50_disp_priv *priv, int or, u32 data) { diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/priv.h b/drivers/gpu/drm/nouveau/core/engine/disp/priv.h new file mode 100644 index 00000000000..26e9a42569c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/priv.h @@ -0,0 +1,42 @@ +#ifndef __NVKM_DISP_PRIV_H__ +#define __NVKM_DISP_PRIV_H__ + +#include <subdev/bios.h> +#include <subdev/bios/dcb.h> +#include <subdev/bios/conn.h> + +#include <engine/disp.h> + +struct nouveau_disp_impl { + struct nouveau_oclass base; + struct nouveau_oclass **outp; + struct nouveau_oclass **conn; +}; + +#define nouveau_disp_create(p,e,c,h,i,x,d) \ + nouveau_disp_create_((p), (e), (c), (h), (i), (x), \ + sizeof(**d), (void **)d) +#define nouveau_disp_destroy(d) ({ \ + struct nouveau_disp *disp = (d); \ + _nouveau_disp_dtor(nv_object(disp)); \ +}) +#define nouveau_disp_init(d) ({ \ + struct nouveau_disp *disp = (d); \ + _nouveau_disp_init(nv_object(disp)); \ +}) +#define nouveau_disp_fini(d,s) ({ \ + struct nouveau_disp *disp = (d); \ + _nouveau_disp_fini(nv_object(disp), (s)); \ +}) + +int nouveau_disp_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int heads, + const char *, const char *, int, void **); +void _nouveau_disp_dtor(struct nouveau_object *); +int _nouveau_disp_init(struct nouveau_object *); +int _nouveau_disp_fini(struct nouveau_object *, bool); + +extern struct nouveau_oclass *nvkm_output_oclass; +extern struct nouveau_oclass *nvkm_connector_oclass; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index 526b7524289..7a1ebdfa9e1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c @@ -47,8 +47,12 @@ 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; @@ -56,6 +60,13 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) 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: @@ -71,6 +82,24 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) 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); } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c index eea3ef59693..05487cda84a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c @@ -29,19 +29,21 @@ #include <subdev/bios/dcb.h> #include <subdev/bios/dp.h> #include <subdev/bios/init.h> +#include <subdev/timer.h> #include "nv50.h" +#include "outpdp.h" static inline u32 -nv94_sor_soff(struct dcb_output *outp) +nv94_sor_soff(struct nvkm_output_dp *outp) { - return (ffs(outp->or) - 1) * 0x800; + return (ffs(outp->base.info.or) - 1) * 0x800; } static inline u32 -nv94_sor_loff(struct dcb_output *outp) +nv94_sor_loff(struct nvkm_output_dp *outp) { - return nv94_sor_soff(outp) + !(outp->sorconf.link & 1) * 0x80; + return nv94_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80; } static inline u32 @@ -55,77 +57,96 @@ nv94_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane) } static int -nv94_sor_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int pattern) +nv94_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) { - struct nv50_disp_priv *priv = (void *)disp; + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); const u32 loff = nv94_sor_loff(outp); nv_mask(priv, 0x61c10c + loff, 0x0f000000, pattern << 24); return 0; } +int +nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) +{ + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); + const u32 soff = nv94_sor_soff(outp); + const u32 loff = nv94_sor_loff(outp); + u32 mask = 0, i; + + for (i = 0; i < nr; i++) + mask |= 1 << (nv94_sor_dp_lane_map(priv, i) >> 3); + + nv_mask(priv, 0x61c130 + loff, 0x0000000f, mask); + nv_mask(priv, 0x61c034 + soff, 0x80000000, 0x80000000); + nv_wait(priv, 0x61c034 + soff, 0x80000000, 0x00000000); + return 0; +} + static int -nv94_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int link_nr, int link_bw, bool enh_frame) +nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) { - struct nv50_disp_priv *priv = (void *)disp; + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); const u32 soff = nv94_sor_soff(outp); const u32 loff = nv94_sor_loff(outp); u32 dpctrl = 0x00000000; u32 clksor = 0x00000000; - u32 lane = 0; - int i; - dpctrl |= ((1 << link_nr) - 1) << 16; - if (enh_frame) + dpctrl |= ((1 << nr) - 1) << 16; + if (ef) dpctrl |= 0x00004000; - if (link_bw > 0x06) + if (bw > 0x06) clksor |= 0x00040000; - for (i = 0; i < link_nr; i++) - lane |= 1 << (nv94_sor_dp_lane_map(priv, i) >> 3); - nv_mask(priv, 0x614300 + soff, 0x000c0000, clksor); nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl); - nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane); return 0; } static int -nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane, int swing, int preem) +nv94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) { - struct nouveau_bios *bios = nouveau_bios(disp); - struct nv50_disp_priv *priv = (void *)disp; - const u32 shift = nv94_sor_dp_lane_map(priv, lane); + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); + struct nouveau_bios *bios = nouveau_bios(priv); + const u32 shift = nv94_sor_dp_lane_map(priv, ln); const u32 loff = nv94_sor_loff(outp); u32 addr, data[3]; u8 ver, hdr, cnt, len; struct nvbios_dpout info; struct nvbios_dpcfg ocfg; - addr = nvbios_dpout_match(bios, outp->hasht, outp->hashm, + addr = nvbios_dpout_match(bios, outp->base.info.hasht, + outp->base.info.hashm, &ver, &hdr, &cnt, &len, &info); if (!addr) return -ENODEV; - addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem, + addr = nvbios_dpcfg_match(bios, addr, 0, vs, pe, &ver, &hdr, &cnt, &len, &ocfg); if (!addr) return -EINVAL; data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); - data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); - nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift)); - nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift)); - nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8)); + data[2] = nv_rd32(priv, 0x61c130 + loff); + if ((data[2] & 0x0000ff00) < (ocfg.tx_pu << 8) || ln == 0) + data[2] = (data[2] & ~0x0000ff00) | (ocfg.tx_pu << 8); + nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift)); + nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift)); + nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8)); return 0; } -const struct nouveau_dp_func -nv94_sor_dp_func = { +struct nvkm_output_dp_impl +nv94_sor_dp_impl = { + .base.base.handle = DCB_OUTPUT_DP, + .base.base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_output_dp_ctor, + .dtor = _nvkm_output_dp_dtor, + .init = _nvkm_output_dp_init, + .fini = _nvkm_output_dp_fini, + }, .pattern = nv94_sor_dp_pattern, + .lnk_pwr = nv94_sor_dp_lnk_pwr, .lnk_ctl = nv94_sor_dp_lnk_ctl, .drv_ctl = nv94_sor_dp_drv_ctl, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c index d2df572f16a..97f0e9cd3d4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c @@ -29,19 +29,20 @@ #include <subdev/bios/dcb.h> #include <subdev/bios/dp.h> #include <subdev/bios/init.h> +#include <subdev/timer.h> #include "nv50.h" static inline u32 -nvd0_sor_soff(struct dcb_output *outp) +nvd0_sor_soff(struct nvkm_output_dp *outp) { - return (ffs(outp->or) - 1) * 0x800; + return (ffs(outp->base.info.or) - 1) * 0x800; } static inline u32 -nvd0_sor_loff(struct dcb_output *outp) +nvd0_sor_loff(struct nvkm_output_dp *outp) { - return nvd0_sor_soff(outp) + !(outp->sorconf.link & 1) * 0x80; + return nvd0_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80; } static inline u32 @@ -52,77 +53,80 @@ nvd0_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane) } static int -nvd0_sor_dp_pattern(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int pattern) +nvd0_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) { - struct nv50_disp_priv *priv = (void *)disp; + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); const u32 loff = nvd0_sor_loff(outp); nv_mask(priv, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern); return 0; } static int -nvd0_sor_dp_lnk_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int link_nr, int link_bw, bool enh_frame) +nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) { - struct nv50_disp_priv *priv = (void *)disp; + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); const u32 soff = nvd0_sor_soff(outp); const u32 loff = nvd0_sor_loff(outp); u32 dpctrl = 0x00000000; u32 clksor = 0x00000000; - u32 lane = 0; - int i; - clksor |= link_bw << 18; - dpctrl |= ((1 << link_nr) - 1) << 16; - if (enh_frame) + clksor |= bw << 18; + dpctrl |= ((1 << nr) - 1) << 16; + if (ef) dpctrl |= 0x00004000; - for (i = 0; i < link_nr; i++) - lane |= 1 << (nvd0_sor_dp_lane_map(priv, i) >> 3); - nv_mask(priv, 0x612300 + soff, 0x007c0000, clksor); nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl); - nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane); return 0; } static int -nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, - int head, int lane, int swing, int preem) +nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) { - struct nouveau_bios *bios = nouveau_bios(disp); - struct nv50_disp_priv *priv = (void *)disp; - const u32 shift = nvd0_sor_dp_lane_map(priv, lane); + struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); + struct nouveau_bios *bios = nouveau_bios(priv); + const u32 shift = nvd0_sor_dp_lane_map(priv, ln); const u32 loff = nvd0_sor_loff(outp); - u32 addr, data[3]; + u32 addr, data[4]; u8 ver, hdr, cnt, len; struct nvbios_dpout info; struct nvbios_dpcfg ocfg; - addr = nvbios_dpout_match(bios, outp->hasht, outp->hashm, + addr = nvbios_dpout_match(bios, outp->base.info.hasht, + outp->base.info.hashm, &ver, &hdr, &cnt, &len, &info); if (!addr) return -ENODEV; - addr = nvbios_dpcfg_match(bios, addr, 0, swing, preem, + addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe, &ver, &hdr, &cnt, &len, &ocfg); if (!addr) return -EINVAL; data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); - data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); - nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift)); - nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift)); - nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8)); - nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000); + data[2] = nv_rd32(priv, 0x61c130 + loff); + if ((data[2] & 0x0000ff00) < (ocfg.tx_pu << 8) || ln == 0) + data[2] = (data[2] & ~0x0000ff00) | (ocfg.tx_pu << 8); + nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift)); + nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift)); + nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8)); + data[3] = nv_rd32(priv, 0x61c13c + loff) & ~(0x000000ff << shift); + nv_wr32(priv, 0x61c13c + loff, data[3] | (ocfg.pc << shift)); return 0; } -const struct nouveau_dp_func -nvd0_sor_dp_func = { +struct nvkm_output_dp_impl +nvd0_sor_dp_impl = { + .base.base.handle = DCB_OUTPUT_DP, + .base.base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_output_dp_ctor, + .dtor = _nvkm_output_dp_dtor, + .init = _nvkm_output_dp_init, + .fini = _nvkm_output_dp_fini, + }, .pattern = nvd0_sor_dp_pattern, + .lnk_pwr = nv94_sor_dp_lnk_pwr, .lnk_ctl = nvd0_sor_dp_lnk_ctl, .drv_ctl = nvd0_sor_dp_drv_ctl, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c index 944e73ac485..1cfb3bb9013 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c @@ -53,6 +53,9 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng, 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: break; default: return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/core/engine/falcon.c b/drivers/gpu/drm/nouveau/core/engine/falcon.c index 5e077e4ed7f..2914646c870 100644 --- a/drivers/gpu/drm/nouveau/core/engine/falcon.c +++ b/drivers/gpu/drm/nouveau/core/engine/falcon.c @@ -119,7 +119,7 @@ _nouveau_falcon_init(struct nouveau_object *object) snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03x", device->chipset, falcon->addr >> 12); - ret = request_firmware(&fw, name, &device->pdev->dev); + ret = request_firmware(&fw, name, nv_device_base(device)); if (ret == 0) { falcon->code.data = vmemdup(fw->data, fw->size); falcon->code.size = fw->size; @@ -138,7 +138,7 @@ _nouveau_falcon_init(struct nouveau_object *object) snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xd", device->chipset, falcon->addr >> 12); - ret = request_firmware(&fw, name, &device->pdev->dev); + ret = request_firmware(&fw, name, nv_device_base(device)); if (ret) { nv_error(falcon, "unable to load firmware data\n"); return ret; @@ -153,7 +153,7 @@ _nouveau_falcon_init(struct nouveau_object *object) snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xc", device->chipset, falcon->addr >> 12); - ret = request_firmware(&fw, name, &device->pdev->dev); + ret = request_firmware(&fw, name, nv_device_base(device)); if (ret) { nv_error(falcon, "unable to load firmware code\n"); return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index d3ec436d9cb..56ed3d73bf8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -86,12 +86,12 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, } /* map fifo control registers */ - chan->user = ioremap(pci_resource_start(device->pdev, bar) + addr + + chan->user = ioremap(nv_device_resource_start(device, bar) + addr + (chan->chid * size), size); if (!chan->user) return -EFAULT; - nouveau_event_trigger(priv->cevent, 0); + nouveau_event_trigger(priv->cevent, 1, 0); chan->size = size; return 0; @@ -194,11 +194,11 @@ nouveau_fifo_create_(struct nouveau_object *parent, if (!priv->channel) return -ENOMEM; - ret = nouveau_event_create(1, &priv->cevent); + ret = nouveau_event_create(1, 1, &priv->cevent); if (ret) return ret; - ret = nouveau_event_create(1, &priv->uevent); + ret = nouveau_event_create(1, 1, &priv->uevent); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c new file mode 100644 index 00000000000..327456eae96 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "nve0.h" + +struct nouveau_oclass * +gk20a_fifo_oclass = &(struct nve0_fifo_impl) { + .base.handle = NV_ENGINE(FIFO, 0xea), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nve0_fifo_ctor, + .dtor = nve0_fifo_dtor, + .init = nve0_fifo_init, + .fini = nve0_fifo_fini, + }, + .channels = 128, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index 54f26cc801c..c61b16a6388 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c @@ -539,7 +539,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) } if (status & 0x40000000) { - nouveau_event_trigger(priv->base.uevent, 0); + nouveau_event_trigger(priv->base.uevent, 1, 0); nv_wr32(priv, 0x002100, 0x40000000); status &= ~0x40000000; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index fe0f41e65d9..6e5ac16e546 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -389,14 +389,14 @@ nv84_fifo_cclass = { ******************************************************************************/ static void -nv84_fifo_uevent_enable(struct nouveau_event *event, int index) +nv84_fifo_uevent_enable(struct nouveau_event *event, int type, int index) { struct nv84_fifo_priv *priv = event->priv; nv_mask(priv, 0x002140, 0x40000000, 0x40000000); } static void -nv84_fifo_uevent_disable(struct nouveau_event *event, int index) +nv84_fifo_uevent_disable(struct nouveau_event *event, int type, int index) { struct nv84_fifo_priv *priv = event->priv; nv_mask(priv, 0x002140, 0x40000000, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index b22a33f0702..ae4a4dc5642 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -41,8 +41,16 @@ struct nvc0_fifo_priv { struct nouveau_fifo base; - struct nouveau_gpuobj *playlist[2]; - int cur_playlist; + + struct work_struct fault; + u64 mask; + + struct { + struct nouveau_gpuobj *mem[2]; + int active; + wait_queue_head_t wait; + } runlist; + struct { struct nouveau_gpuobj *mem; struct nouveau_vma bar; @@ -58,6 +66,11 @@ struct nvc0_fifo_base { struct nvc0_fifo_chan { struct nouveau_fifo_chan base; + enum { + STOPPED, + RUNNING, + KILLED + } state; }; /******************************************************************************* @@ -65,29 +78,33 @@ struct nvc0_fifo_chan { ******************************************************************************/ static void -nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) +nvc0_fifo_runlist_update(struct nvc0_fifo_priv *priv) { struct nouveau_bar *bar = nouveau_bar(priv); struct nouveau_gpuobj *cur; int i, p; mutex_lock(&nv_subdev(priv)->mutex); - cur = priv->playlist[priv->cur_playlist]; - priv->cur_playlist = !priv->cur_playlist; + cur = priv->runlist.mem[priv->runlist.active]; + priv->runlist.active = !priv->runlist.active; for (i = 0, p = 0; i < 128; i++) { - if (!(nv_rd32(priv, 0x003004 + (i * 8)) & 1)) - continue; - nv_wo32(cur, p + 0, i); - nv_wo32(cur, p + 4, 0x00000004); - p += 8; + struct nvc0_fifo_chan *chan = (void *)priv->base.channel[i]; + if (chan && chan->state == RUNNING) { + nv_wo32(cur, p + 0, i); + nv_wo32(cur, p + 4, 0x00000004); + p += 8; + } } bar->flush(bar); nv_wr32(priv, 0x002270, cur->addr >> 12); nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3)); - if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000)) - nv_error(priv, "playlist update failed\n"); + + if (wait_event_timeout(priv->runlist.wait, + !(nv_rd32(priv, 0x00227c) & 0x00100000), + msecs_to_jiffies(2000)) == 0) + nv_error(priv, "runlist update timeout\n"); mutex_unlock(&nv_subdev(priv)->mutex); } @@ -239,30 +256,32 @@ nvc0_fifo_chan_init(struct nouveau_object *object) return ret; nv_wr32(priv, 0x003000 + (chid * 8), 0xc0000000 | base->addr >> 12); - nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001); - nvc0_fifo_playlist_update(priv); + + if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) { + nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001); + nvc0_fifo_runlist_update(priv); + } + return 0; } +static void nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv); + static int nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend) { struct nvc0_fifo_priv *priv = (void *)object->engine; struct nvc0_fifo_chan *chan = (void *)object; u32 chid = chan->base.chid; - u32 mask, engine; - nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); - nvc0_fifo_playlist_update(priv); - mask = nv_rd32(priv, 0x0025a4); - for (engine = 0; mask && engine < 16; engine++) { - if (!(mask & (1 << engine))) - continue; - nv_mask(priv, 0x0025a8 + (engine * 4), 0x00000000, 0x00000000); - mask &= ~(1 << engine); + if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) { + nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); + nvc0_fifo_runlist_update(priv); } - nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); + nvc0_fifo_intr_engine(priv); + + nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); return nouveau_fifo_channel_fini(&chan->base, suspend); } @@ -345,11 +364,177 @@ nvc0_fifo_cclass = { * PFIFO engine ******************************************************************************/ -static const struct nouveau_enum nvc0_fifo_fault_unit[] = { +static inline int +nvc0_fifo_engidx(struct nvc0_fifo_priv *priv, u32 engn) +{ + switch (engn) { + case NVDEV_ENGINE_GR : engn = 0; break; + case NVDEV_ENGINE_BSP : engn = 1; break; + case NVDEV_ENGINE_PPP : engn = 2; break; + case NVDEV_ENGINE_VP : engn = 3; break; + case NVDEV_ENGINE_COPY0: engn = 4; break; + case NVDEV_ENGINE_COPY1: engn = 5; break; + default: + return -1; + } + + return engn; +} + +static inline struct nouveau_engine * +nvc0_fifo_engine(struct nvc0_fifo_priv *priv, u32 engn) +{ + switch (engn) { + case 0: engn = NVDEV_ENGINE_GR; break; + case 1: engn = NVDEV_ENGINE_BSP; break; + case 2: engn = NVDEV_ENGINE_PPP; break; + case 3: engn = NVDEV_ENGINE_VP; break; + case 4: engn = NVDEV_ENGINE_COPY0; break; + case 5: engn = NVDEV_ENGINE_COPY1; break; + default: + return NULL; + } + + return nouveau_engine(priv, engn); +} + +static void +nvc0_fifo_recover_work(struct work_struct *work) +{ + struct nvc0_fifo_priv *priv = container_of(work, typeof(*priv), fault); + struct nouveau_object *engine; + unsigned long flags; + u32 engn, engm = 0; + u64 mask, todo; + + spin_lock_irqsave(&priv->base.lock, flags); + mask = priv->mask; + priv->mask = 0ULL; + spin_unlock_irqrestore(&priv->base.lock, flags); + + for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) + engm |= 1 << nvc0_fifo_engidx(priv, engn); + nv_mask(priv, 0x002630, engm, engm); + + for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) { + if ((engine = (void *)nouveau_engine(priv, engn))) { + nv_ofuncs(engine)->fini(engine, false); + WARN_ON(nv_ofuncs(engine)->init(engine)); + } + } + + nvc0_fifo_runlist_update(priv); + nv_wr32(priv, 0x00262c, engm); + nv_mask(priv, 0x002630, engm, 0x00000000); +} + +static void +nvc0_fifo_recover(struct nvc0_fifo_priv *priv, struct nouveau_engine *engine, + struct nvc0_fifo_chan *chan) +{ + struct nouveau_object *engobj = nv_object(engine); + u32 chid = chan->base.chid; + unsigned long flags; + + nv_error(priv, "%s engine fault on channel %d, recovering...\n", + nv_subdev(engine)->name, chid); + + nv_mask(priv, 0x003004 + (chid * 0x08), 0x00000001, 0x00000000); + chan->state = KILLED; + + spin_lock_irqsave(&priv->base.lock, flags); + priv->mask |= 1ULL << nv_engidx(engobj); + spin_unlock_irqrestore(&priv->base.lock, flags); + schedule_work(&priv->fault); +} + +static int +nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data) +{ + struct nvc0_fifo_chan *chan = NULL; + struct nouveau_handle *bind; + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&priv->base.lock, flags); + if (likely(chid >= priv->base.min && chid <= priv->base.max)) + chan = (void *)priv->base.channel[chid]; + if (unlikely(!chan)) + goto out; + + bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e); + if (likely(bind)) { + if (!mthd || !nv_call(bind->object, mthd, data)) + ret = 0; + nouveau_namedb_put(bind); + } + +out: + spin_unlock_irqrestore(&priv->base.lock, flags); + return ret; +} + +static const struct nouveau_enum +nvc0_fifo_sched_reason[] = { + { 0x0a, "CTXSW_TIMEOUT" }, + {} +}; + +static void +nvc0_fifo_intr_sched_ctxsw(struct nvc0_fifo_priv *priv) +{ + struct nouveau_engine *engine; + struct nvc0_fifo_chan *chan; + u32 engn; + + for (engn = 0; engn < 6; engn++) { + u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04)); + u32 busy = (stat & 0x80000000); + u32 save = (stat & 0x00100000); /* maybe? */ + u32 unk0 = (stat & 0x00040000); + u32 unk1 = (stat & 0x00001000); + u32 chid = (stat & 0x0000007f); + (void)save; + + if (busy && unk0 && unk1) { + if (!(chan = (void *)priv->base.channel[chid])) + continue; + if (!(engine = nvc0_fifo_engine(priv, engn))) + continue; + nvc0_fifo_recover(priv, engine, chan); + } + } +} + +static void +nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv) +{ + u32 intr = nv_rd32(priv, 0x00254c); + u32 code = intr & 0x000000ff; + const struct nouveau_enum *en; + char enunk[6] = ""; + + en = nouveau_enum_find(nvc0_fifo_sched_reason, code); + if (!en) + snprintf(enunk, sizeof(enunk), "UNK%02x", code); + + nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk); + + switch (code) { + case 0x0a: + nvc0_fifo_intr_sched_ctxsw(priv); + break; + default: + break; + } +} + +static const struct nouveau_enum +nvc0_fifo_fault_engine[] = { { 0x00, "PGRAPH", NULL, NVDEV_ENGINE_GR }, - { 0x03, "PEEPHOLE" }, - { 0x04, "BAR1" }, - { 0x05, "BAR3" }, + { 0x03, "PEEPHOLE", NULL, NVDEV_ENGINE_IFB }, + { 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR }, + { 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM }, { 0x07, "PFIFO", NULL, NVDEV_ENGINE_FIFO }, { 0x10, "PBSP", NULL, NVDEV_ENGINE_BSP }, { 0x11, "PPPP", NULL, NVDEV_ENGINE_PPP }, @@ -361,7 +546,8 @@ static const struct nouveau_enum nvc0_fifo_fault_unit[] = { {} }; -static const struct nouveau_enum nvc0_fifo_fault_reason[] = { +static const struct nouveau_enum +nvc0_fifo_fault_reason[] = { { 0x00, "PT_NOT_PRESENT" }, { 0x01, "PT_TOO_SHORT" }, { 0x02, "PAGE_NOT_PRESENT" }, @@ -374,7 +560,8 @@ static const struct nouveau_enum nvc0_fifo_fault_reason[] = { {} }; -static const struct nouveau_enum nvc0_fifo_fault_hubclient[] = { +static const struct nouveau_enum +nvc0_fifo_fault_hubclient[] = { { 0x01, "PCOPY0" }, { 0x02, "PCOPY1" }, { 0x04, "DISPATCH" }, @@ -392,7 +579,8 @@ static const struct nouveau_enum nvc0_fifo_fault_hubclient[] = { {} }; -static const struct nouveau_enum nvc0_fifo_fault_gpcclient[] = { +static const struct nouveau_enum +nvc0_fifo_fault_gpcclient[] = { { 0x01, "TEX" }, { 0x0c, "ESETUP" }, { 0x0e, "CTXCTL" }, @@ -400,92 +588,92 @@ static const struct nouveau_enum nvc0_fifo_fault_gpcclient[] = { {} }; -static const struct nouveau_bitfield nvc0_fifo_subfifo_intr[] = { -/* { 0x00008000, "" } seen with null ib push */ - { 0x00200000, "ILLEGAL_MTHD" }, - { 0x00800000, "EMPTY_SUBC" }, - {} -}; - static void -nvc0_fifo_isr_vm_fault(struct nvc0_fifo_priv *priv, int unit) +nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit) { u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10)); u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10)); u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10)); u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10)); + u32 gpc = (stat & 0x1f000000) >> 24; u32 client = (stat & 0x00001f00) >> 8; - const struct nouveau_enum *en; - struct nouveau_engine *engine; - struct nouveau_object *engctx = NULL; - - switch (unit) { - case 3: /* PEEPHOLE */ - nv_mask(priv, 0x001718, 0x00000000, 0x00000000); - break; - case 4: /* BAR1 */ - nv_mask(priv, 0x001704, 0x00000000, 0x00000000); - break; - case 5: /* BAR3 */ - nv_mask(priv, 0x001714, 0x00000000, 0x00000000); - break; - default: - break; + u32 write = (stat & 0x00000080); + u32 hub = (stat & 0x00000040); + u32 reason = (stat & 0x0000000f); + struct nouveau_object *engctx = NULL, *object; + struct nouveau_engine *engine = NULL; + const struct nouveau_enum *er, *eu, *ec; + char erunk[6] = ""; + char euunk[6] = ""; + char ecunk[6] = ""; + char gpcid[3] = ""; + + er = nouveau_enum_find(nvc0_fifo_fault_reason, reason); + if (!er) + snprintf(erunk, sizeof(erunk), "UNK%02X", reason); + + eu = nouveau_enum_find(nvc0_fifo_fault_engine, unit); + if (eu) { + switch (eu->data2) { + case NVDEV_SUBDEV_BAR: + nv_mask(priv, 0x001704, 0x00000000, 0x00000000); + break; + case NVDEV_SUBDEV_INSTMEM: + nv_mask(priv, 0x001714, 0x00000000, 0x00000000); + break; + case NVDEV_ENGINE_IFB: + nv_mask(priv, 0x001718, 0x00000000, 0x00000000); + break; + default: + engine = nouveau_engine(priv, eu->data2); + if (engine) + engctx = nouveau_engctx_get(engine, inst); + break; + } + } else { + snprintf(euunk, sizeof(euunk), "UNK%02x", unit); } - nv_error(priv, "%s fault at 0x%010llx [", (stat & 0x00000080) ? - "write" : "read", (u64)vahi << 32 | valo); - nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f); - pr_cont("] from "); - en = nouveau_enum_print(nvc0_fifo_fault_unit, unit); - if (stat & 0x00000040) { - pr_cont("/"); - nouveau_enum_print(nvc0_fifo_fault_hubclient, client); + if (hub) { + ec = nouveau_enum_find(nvc0_fifo_fault_hubclient, client); } else { - pr_cont("/GPC%d/", (stat & 0x1f000000) >> 24); - nouveau_enum_print(nvc0_fifo_fault_gpcclient, client); + ec = nouveau_enum_find(nvc0_fifo_fault_gpcclient, client); + snprintf(gpcid, sizeof(gpcid), "%d", gpc); } - if (en && en->data2) { - engine = nouveau_engine(priv, en->data2); - if (engine) - engctx = nouveau_engctx_get(engine, inst); - + if (!ec) + snprintf(ecunk, sizeof(ecunk), "UNK%02x", client); + + nv_error(priv, "%s fault at 0x%010llx [%s] from %s/%s%s%s%s on " + "channel 0x%010llx [%s]\n", write ? "write" : "read", + (u64)vahi << 32 | valo, er ? er->name : erunk, + eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/", + ec ? ec->name : ecunk, (u64)inst << 12, + nouveau_client_name(engctx)); + + object = engctx; + while (object) { + switch (nv_mclass(object)) { + case NVC0_CHANNEL_IND_CLASS: + nvc0_fifo_recover(priv, engine, (void *)object); + break; + } + object = object->parent; } - pr_cont(" on channel 0x%010llx [%s]\n", (u64)inst << 12, - nouveau_client_name(engctx)); nouveau_engctx_put(engctx); } -static int -nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data) -{ - struct nvc0_fifo_chan *chan = NULL; - struct nouveau_handle *bind; - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&priv->base.lock, flags); - if (likely(chid >= priv->base.min && chid <= priv->base.max)) - chan = (void *)priv->base.channel[chid]; - if (unlikely(!chan)) - goto out; - - bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e); - if (likely(bind)) { - if (!mthd || !nv_call(bind->object, mthd, data)) - ret = 0; - nouveau_namedb_put(bind); - } - -out: - spin_unlock_irqrestore(&priv->base.lock, flags); - return ret; -} +static const struct nouveau_bitfield +nvc0_fifo_pbdma_intr[] = { +/* { 0x00008000, "" } seen with null ib push */ + { 0x00200000, "ILLEGAL_MTHD" }, + { 0x00800000, "EMPTY_SUBC" }, + {} +}; static void -nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit) +nvc0_fifo_intr_pbdma(struct nvc0_fifo_priv *priv, int unit) { u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000)); u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000)); @@ -501,11 +689,11 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit) } if (show) { - nv_error(priv, "SUBFIFO%d:", unit); - nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show); + nv_error(priv, "PBDMA%d:", unit); + nouveau_bitfield_print(nvc0_fifo_pbdma_intr, show); pr_cont("\n"); nv_error(priv, - "SUBFIFO%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", + "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", unit, chid, nouveau_client_name_for_fifo_chid(&priv->base, chid), subc, mthd, data); @@ -516,6 +704,56 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit) } static void +nvc0_fifo_intr_runlist(struct nvc0_fifo_priv *priv) +{ + u32 intr = nv_rd32(priv, 0x002a00); + + if (intr & 0x10000000) { + wake_up(&priv->runlist.wait); + nv_wr32(priv, 0x002a00, 0x10000000); + intr &= ~0x10000000; + } + + if (intr) { + nv_error(priv, "RUNLIST 0x%08x\n", intr); + nv_wr32(priv, 0x002a00, intr); + } +} + +static void +nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) +{ + u32 intr = nv_rd32(priv, 0x0025a8 + (engn * 0x04)); + u32 inte = nv_rd32(priv, 0x002628); + u32 unkn; + + for (unkn = 0; unkn < 8; unkn++) { + u32 ints = (intr >> (unkn * 0x04)) & inte; + if (ints & 0x1) { + nouveau_event_trigger(priv->base.uevent, 1, 0); + ints &= ~1; + } + if (ints) { + nv_error(priv, "ENGINE %d %d %01x", engn, unkn, ints); + nv_mask(priv, 0x002628, ints, 0); + } + } + + nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr); +} + +static void +nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv) +{ + u32 mask = nv_rd32(priv, 0x0025a4); + while (mask) { + u32 unit = __ffs(mask); + nvc0_fifo_intr_engine_unit(priv, unit); + mask &= ~(1 << unit); + } +} + +static void nvc0_fifo_intr(struct nouveau_subdev *subdev) { struct nvc0_fifo_priv *priv = (void *)subdev; @@ -530,8 +768,7 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } if (stat & 0x00000100) { - u32 intr = nv_rd32(priv, 0x00254c); - nv_warn(priv, "INTR 0x00000100: 0x%08x\n", intr); + nvc0_fifo_intr_sched(priv); nv_wr32(priv, 0x002100, 0x00000100); stat &= ~0x00000100; } @@ -551,64 +788,53 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } if (stat & 0x10000000) { - u32 units = nv_rd32(priv, 0x00259c); - u32 u = units; - - while (u) { - int i = ffs(u) - 1; - nvc0_fifo_isr_vm_fault(priv, i); - u &= ~(1 << i); + u32 mask = nv_rd32(priv, 0x00259c); + while (mask) { + u32 unit = __ffs(mask); + nvc0_fifo_intr_fault(priv, unit); + nv_wr32(priv, 0x00259c, (1 << unit)); + mask &= ~(1 << unit); } - - nv_wr32(priv, 0x00259c, units); stat &= ~0x10000000; } if (stat & 0x20000000) { - u32 units = nv_rd32(priv, 0x0025a0); - u32 u = units; - - while (u) { - int i = ffs(u) - 1; - nvc0_fifo_isr_subfifo_intr(priv, i); - u &= ~(1 << i); + u32 mask = nv_rd32(priv, 0x0025a0); + while (mask) { + u32 unit = __ffs(mask); + nvc0_fifo_intr_pbdma(priv, unit); + nv_wr32(priv, 0x0025a0, (1 << unit)); + mask &= ~(1 << unit); } - - nv_wr32(priv, 0x0025a0, units); stat &= ~0x20000000; } if (stat & 0x40000000) { - u32 intr0 = nv_rd32(priv, 0x0025a4); - u32 intr1 = nv_mask(priv, 0x002a00, 0x00000000, 0x00000); - nv_debug(priv, "INTR 0x40000000: 0x%08x 0x%08x\n", - intr0, intr1); + nvc0_fifo_intr_runlist(priv); stat &= ~0x40000000; } if (stat & 0x80000000) { - u32 intr = nv_mask(priv, 0x0025a8, 0x00000000, 0x00000000); - nouveau_event_trigger(priv->base.uevent, 0); - nv_debug(priv, "INTR 0x80000000: 0x%08x\n", intr); + nvc0_fifo_intr_engine(priv); stat &= ~0x80000000; } if (stat) { - nv_fatal(priv, "unhandled status 0x%08x\n", stat); + nv_error(priv, "INTR 0x%08x\n", stat); + nv_mask(priv, 0x002140, stat, 0x00000000); nv_wr32(priv, 0x002100, stat); - nv_wr32(priv, 0x002140, 0); } } static void -nvc0_fifo_uevent_enable(struct nouveau_event *event, int index) +nvc0_fifo_uevent_enable(struct nouveau_event *event, int type, int index) { struct nvc0_fifo_priv *priv = event->priv; nv_mask(priv, 0x002140, 0x80000000, 0x80000000); } static void -nvc0_fifo_uevent_disable(struct nouveau_event *event, int index) +nvc0_fifo_uevent_disable(struct nouveau_event *event, int type, int index) { struct nvc0_fifo_priv *priv = event->priv; nv_mask(priv, 0x002140, 0x80000000, 0x00000000); @@ -627,16 +853,20 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; + INIT_WORK(&priv->fault, nvc0_fifo_recover_work); + ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0, - &priv->playlist[0]); + &priv->runlist.mem[0]); if (ret) return ret; ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0, - &priv->playlist[1]); + &priv->runlist.mem[1]); if (ret) return ret; + init_waitqueue_head(&priv->runlist.wait); + ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0, &priv->user.mem); if (ret) @@ -665,8 +895,8 @@ nvc0_fifo_dtor(struct nouveau_object *object) nouveau_gpuobj_unmap(&priv->user.bar); nouveau_gpuobj_ref(NULL, &priv->user.mem); - nouveau_gpuobj_ref(NULL, &priv->playlist[1]); - nouveau_gpuobj_ref(NULL, &priv->playlist[0]); + nouveau_gpuobj_ref(NULL, &priv->runlist.mem[0]); + nouveau_gpuobj_ref(NULL, &priv->runlist.mem[1]); nouveau_fifo_destroy(&priv->base); } @@ -685,9 +915,9 @@ nvc0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002204, 0xffffffff); priv->spoon_nr = hweight32(nv_rd32(priv, 0x002204)); - nv_debug(priv, "%d subfifo(s)\n", priv->spoon_nr); + nv_debug(priv, "%d PBDMA unit(s)\n", priv->spoon_nr); - /* assign engines to subfifos */ + /* assign engines to PBDMAs */ if (priv->spoon_nr >= 3) { nv_wr32(priv, 0x002208, ~(1 << 0)); /* PGRAPH */ nv_wr32(priv, 0x00220c, ~(1 << 1)); /* PVP */ @@ -697,7 +927,7 @@ nvc0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x00221c, ~(1 << 1)); /* PCE1 */ } - /* PSUBFIFO[n] */ + /* PBDMA[n] */ for (i = 0; i < priv->spoon_nr; i++) { nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ @@ -707,10 +937,9 @@ nvc0_fifo_init(struct nouveau_object *object) nv_mask(priv, 0x002200, 0x00000001, 0x00000001); nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12); - nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0x3fffffff); - nv_wr32(priv, 0x002628, 0x00000001); /* makes mthd 0x20 work */ + nv_wr32(priv, 0x002140, 0x7fffffff); + nv_wr32(priv, 0x002628, 0x00000001); /* ENGINE_INTR_EN */ return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 9a850fe1951..298063edb92 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -60,10 +60,15 @@ static const struct { struct nve0_fifo_engn { struct nouveau_gpuobj *runlist[2]; int cur_runlist; + wait_queue_head_t wait; }; struct nve0_fifo_priv { struct nouveau_fifo base; + + struct work_struct fault; + u64 mask; + struct nve0_fifo_engn engine[FIFO_ENGINE_NR]; struct { struct nouveau_gpuobj *mem; @@ -81,6 +86,11 @@ struct nve0_fifo_base { struct nve0_fifo_chan { struct nouveau_fifo_chan base; u32 engine; + enum { + STOPPED, + RUNNING, + KILLED + } state; }; /******************************************************************************* @@ -93,7 +103,6 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine) struct nouveau_bar *bar = nouveau_bar(priv); struct nve0_fifo_engn *engn = &priv->engine[engine]; struct nouveau_gpuobj *cur; - u32 match = (engine << 16) | 0x00000001; int i, p; mutex_lock(&nv_subdev(priv)->mutex); @@ -101,18 +110,21 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine) engn->cur_runlist = !engn->cur_runlist; for (i = 0, p = 0; i < priv->base.max; i++) { - u32 ctrl = nv_rd32(priv, 0x800004 + (i * 8)) & 0x001f0001; - if (ctrl != match) - continue; - nv_wo32(cur, p + 0, i); - nv_wo32(cur, p + 4, 0x00000000); - p += 8; + struct nve0_fifo_chan *chan = (void *)priv->base.channel[i]; + if (chan && chan->state == RUNNING && chan->engine == engine) { + nv_wo32(cur, p + 0, i); + nv_wo32(cur, p + 4, 0x00000000); + p += 8; + } } bar->flush(bar); nv_wr32(priv, 0x002270, cur->addr >> 12); nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); - if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) + + if (wait_event_timeout(engn->wait, !(nv_rd32(priv, 0x002284 + + (engine * 0x08)) & 0x00100000), + msecs_to_jiffies(2000)) == 0) nv_error(priv, "runlist %d update timeout\n", engine); mutex_unlock(&nv_subdev(priv)->mutex); } @@ -129,9 +141,11 @@ nve0_fifo_context_attach(struct nouveau_object *parent, switch (nv_engidx(object->engine)) { case NVDEV_ENGINE_SW : + return 0; case NVDEV_ENGINE_COPY0: case NVDEV_ENGINE_COPY1: case NVDEV_ENGINE_COPY2: + nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12; return 0; case NVDEV_ENGINE_GR : addr = 0x0210; break; case NVDEV_ENGINE_BSP : addr = 0x0270; break; @@ -279,9 +293,13 @@ nve0_fifo_chan_init(struct nouveau_object *object) nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16); nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12); - nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); - nve0_fifo_runlist_update(priv, chan->engine); - nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); + + if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) { + nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); + nve0_fifo_runlist_update(priv, chan->engine); + nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); + } + return 0; } @@ -292,10 +310,12 @@ nve0_fifo_chan_fini(struct nouveau_object *object, bool suspend) struct nve0_fifo_chan *chan = (void *)object; u32 chid = chan->base.chid; - nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800); - nve0_fifo_runlist_update(priv, chan->engine); - nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000); + if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) { + nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800); + nve0_fifo_runlist_update(priv, chan->engine); + } + nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000); return nouveau_fifo_channel_fini(&chan->base, suspend); } @@ -377,14 +397,211 @@ nve0_fifo_cclass = { * PFIFO engine ******************************************************************************/ -static const struct nouveau_enum nve0_fifo_sched_reason[] = { +static inline int +nve0_fifo_engidx(struct nve0_fifo_priv *priv, u32 engn) +{ + switch (engn) { + case NVDEV_ENGINE_GR : + case NVDEV_ENGINE_COPY2: engn = 0; break; + case NVDEV_ENGINE_BSP : engn = 1; break; + case NVDEV_ENGINE_PPP : engn = 2; break; + case NVDEV_ENGINE_VP : engn = 3; break; + case NVDEV_ENGINE_COPY0: engn = 4; break; + case NVDEV_ENGINE_COPY1: engn = 5; break; + case NVDEV_ENGINE_VENC : engn = 6; break; + default: + return -1; + } + + return engn; +} + +static inline struct nouveau_engine * +nve0_fifo_engine(struct nve0_fifo_priv *priv, u32 engn) +{ + if (engn >= ARRAY_SIZE(fifo_engine)) + return NULL; + return nouveau_engine(priv, fifo_engine[engn].subdev); +} + +static void +nve0_fifo_recover_work(struct work_struct *work) +{ + struct nve0_fifo_priv *priv = container_of(work, typeof(*priv), fault); + struct nouveau_object *engine; + unsigned long flags; + u32 engn, engm = 0; + u64 mask, todo; + + spin_lock_irqsave(&priv->base.lock, flags); + mask = priv->mask; + priv->mask = 0ULL; + spin_unlock_irqrestore(&priv->base.lock, flags); + + for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) + engm |= 1 << nve0_fifo_engidx(priv, engn); + nv_mask(priv, 0x002630, engm, engm); + + for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) { + if ((engine = (void *)nouveau_engine(priv, engn))) { + nv_ofuncs(engine)->fini(engine, false); + WARN_ON(nv_ofuncs(engine)->init(engine)); + } + nve0_fifo_runlist_update(priv, nve0_fifo_engidx(priv, engn)); + } + + nv_wr32(priv, 0x00262c, engm); + nv_mask(priv, 0x002630, engm, 0x00000000); +} + +static void +nve0_fifo_recover(struct nve0_fifo_priv *priv, struct nouveau_engine *engine, + struct nve0_fifo_chan *chan) +{ + struct nouveau_object *engobj = nv_object(engine); + u32 chid = chan->base.chid; + unsigned long flags; + + nv_error(priv, "%s engine fault on channel %d, recovering...\n", + nv_subdev(engine)->name, chid); + + nv_mask(priv, 0x800004 + (chid * 0x08), 0x00000800, 0x00000800); + chan->state = KILLED; + + spin_lock_irqsave(&priv->base.lock, flags); + priv->mask |= 1ULL << nv_engidx(engobj); + spin_unlock_irqrestore(&priv->base.lock, flags); + schedule_work(&priv->fault); +} + +static int +nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data) +{ + struct nve0_fifo_chan *chan = NULL; + struct nouveau_handle *bind; + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&priv->base.lock, flags); + if (likely(chid >= priv->base.min && chid <= priv->base.max)) + chan = (void *)priv->base.channel[chid]; + if (unlikely(!chan)) + goto out; + + bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e); + if (likely(bind)) { + if (!mthd || !nv_call(bind->object, mthd, data)) + ret = 0; + nouveau_namedb_put(bind); + } + +out: + spin_unlock_irqrestore(&priv->base.lock, flags); + return ret; +} + +static const struct nouveau_enum +nve0_fifo_bind_reason[] = { + { 0x01, "BIND_NOT_UNBOUND" }, + { 0x02, "SNOOP_WITHOUT_BAR1" }, + { 0x03, "UNBIND_WHILE_RUNNING" }, + { 0x05, "INVALID_RUNLIST" }, + { 0x06, "INVALID_CTX_TGT" }, + { 0x0b, "UNBIND_WHILE_PARKED" }, + {} +}; + +static void +nve0_fifo_intr_bind(struct nve0_fifo_priv *priv) +{ + u32 intr = nv_rd32(priv, 0x00252c); + u32 code = intr & 0x000000ff; + const struct nouveau_enum *en; + char enunk[6] = ""; + + en = nouveau_enum_find(nve0_fifo_bind_reason, code); + if (!en) + snprintf(enunk, sizeof(enunk), "UNK%02x", code); + + nv_error(priv, "BIND_ERROR [ %s ]\n", en ? en->name : enunk); +} + +static const struct nouveau_enum +nve0_fifo_sched_reason[] = { { 0x0a, "CTXSW_TIMEOUT" }, {} }; -static const struct nouveau_enum nve0_fifo_fault_engine[] = { +static void +nve0_fifo_intr_sched_ctxsw(struct nve0_fifo_priv *priv) +{ + struct nouveau_engine *engine; + struct nve0_fifo_chan *chan; + u32 engn; + + for (engn = 0; engn < ARRAY_SIZE(fifo_engine); engn++) { + u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04)); + u32 busy = (stat & 0x80000000); + u32 next = (stat & 0x07ff0000) >> 16; + u32 chsw = (stat & 0x00008000); + u32 save = (stat & 0x00004000); + u32 load = (stat & 0x00002000); + u32 prev = (stat & 0x000007ff); + u32 chid = load ? next : prev; + (void)save; + + if (busy && chsw) { + if (!(chan = (void *)priv->base.channel[chid])) + continue; + if (!(engine = nve0_fifo_engine(priv, engn))) + continue; + nve0_fifo_recover(priv, engine, chan); + } + } +} + +static void +nve0_fifo_intr_sched(struct nve0_fifo_priv *priv) +{ + u32 intr = nv_rd32(priv, 0x00254c); + u32 code = intr & 0x000000ff; + const struct nouveau_enum *en; + char enunk[6] = ""; + + en = nouveau_enum_find(nve0_fifo_sched_reason, code); + if (!en) + snprintf(enunk, sizeof(enunk), "UNK%02x", code); + + nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk); + + switch (code) { + case 0x0a: + nve0_fifo_intr_sched_ctxsw(priv); + break; + default: + break; + } +} + +static void +nve0_fifo_intr_chsw(struct nve0_fifo_priv *priv) +{ + u32 stat = nv_rd32(priv, 0x00256c); + nv_error(priv, "CHSW_ERROR 0x%08x\n", stat); + nv_wr32(priv, 0x00256c, stat); +} + +static void +nve0_fifo_intr_dropped_fault(struct nve0_fifo_priv *priv) +{ + u32 stat = nv_rd32(priv, 0x00259c); + nv_error(priv, "DROPPED_MMU_FAULT 0x%08x\n", stat); +} + +static const struct nouveau_enum +nve0_fifo_fault_engine[] = { { 0x00, "GR", NULL, NVDEV_ENGINE_GR }, - { 0x03, "IFB" }, + { 0x03, "IFB", NULL, NVDEV_ENGINE_IFB }, { 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR }, { 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM }, { 0x07, "PBDMA0", NULL, NVDEV_ENGINE_FIFO }, @@ -402,7 +619,8 @@ static const struct nouveau_enum nve0_fifo_fault_engine[] = { {} }; -static const struct nouveau_enum nve0_fifo_fault_reason[] = { +static const struct nouveau_enum +nve0_fifo_fault_reason[] = { { 0x00, "PDE" }, { 0x01, "PDE_SIZE" }, { 0x02, "PTE" }, @@ -422,7 +640,8 @@ static const struct nouveau_enum nve0_fifo_fault_reason[] = { {} }; -static const struct nouveau_enum nve0_fifo_fault_hubclient[] = { +static const struct nouveau_enum +nve0_fifo_fault_hubclient[] = { { 0x00, "VIP" }, { 0x01, "CE0" }, { 0x02, "CE1" }, @@ -458,7 +677,8 @@ static const struct nouveau_enum nve0_fifo_fault_hubclient[] = { {} }; -static const struct nouveau_enum nve0_fifo_fault_gpcclient[] = { +static const struct nouveau_enum +nve0_fifo_fault_gpcclient[] = { { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" }, { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" }, { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" }, @@ -483,6 +703,82 @@ static const struct nouveau_enum nve0_fifo_fault_gpcclient[] = { {} }; +static void +nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit) +{ + u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10)); + u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10)); + u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10)); + u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10)); + u32 gpc = (stat & 0x1f000000) >> 24; + u32 client = (stat & 0x00001f00) >> 8; + u32 write = (stat & 0x00000080); + u32 hub = (stat & 0x00000040); + u32 reason = (stat & 0x0000000f); + struct nouveau_object *engctx = NULL, *object; + struct nouveau_engine *engine = NULL; + const struct nouveau_enum *er, *eu, *ec; + char erunk[6] = ""; + char euunk[6] = ""; + char ecunk[6] = ""; + char gpcid[3] = ""; + + er = nouveau_enum_find(nve0_fifo_fault_reason, reason); + if (!er) + snprintf(erunk, sizeof(erunk), "UNK%02X", reason); + + eu = nouveau_enum_find(nve0_fifo_fault_engine, unit); + if (eu) { + switch (eu->data2) { + case NVDEV_SUBDEV_BAR: + nv_mask(priv, 0x001704, 0x00000000, 0x00000000); + break; + case NVDEV_SUBDEV_INSTMEM: + nv_mask(priv, 0x001714, 0x00000000, 0x00000000); + break; + case NVDEV_ENGINE_IFB: + nv_mask(priv, 0x001718, 0x00000000, 0x00000000); + break; + default: + engine = nouveau_engine(priv, eu->data2); + if (engine) + engctx = nouveau_engctx_get(engine, inst); + break; + } + } else { + snprintf(euunk, sizeof(euunk), "UNK%02x", unit); + } + + if (hub) { + ec = nouveau_enum_find(nve0_fifo_fault_hubclient, client); + } else { + ec = nouveau_enum_find(nve0_fifo_fault_gpcclient, client); + snprintf(gpcid, sizeof(gpcid), "%d", gpc); + } + + if (!ec) + snprintf(ecunk, sizeof(ecunk), "UNK%02x", client); + + nv_error(priv, "%s fault at 0x%010llx [%s] from %s/%s%s%s%s on " + "channel 0x%010llx [%s]\n", write ? "write" : "read", + (u64)vahi << 32 | valo, er ? er->name : erunk, + eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/", + ec ? ec->name : ecunk, (u64)inst << 12, + nouveau_client_name(engctx)); + + object = engctx; + while (object) { + switch (nv_mclass(object)) { + case NVE0_CHANNEL_IND_CLASS: + nve0_fifo_recover(priv, engine, (void *)object); + break; + } + object = object->parent; + } + + nouveau_engctx_put(engctx); +} + static const struct nouveau_bitfield nve0_fifo_pbdma_intr[] = { { 0x00000001, "MEMREQ" }, { 0x00000002, "MEMACK_TIMEOUT" }, @@ -518,104 +814,6 @@ static const struct nouveau_bitfield nve0_fifo_pbdma_intr[] = { }; static void -nve0_fifo_intr_sched(struct nve0_fifo_priv *priv) -{ - u32 intr = nv_rd32(priv, 0x00254c); - u32 code = intr & 0x000000ff; - nv_error(priv, "SCHED_ERROR ["); - nouveau_enum_print(nve0_fifo_sched_reason, code); - pr_cont("]\n"); -} - -static void -nve0_fifo_intr_chsw(struct nve0_fifo_priv *priv) -{ - u32 stat = nv_rd32(priv, 0x00256c); - nv_error(priv, "CHSW_ERROR 0x%08x\n", stat); - nv_wr32(priv, 0x00256c, stat); -} - -static void -nve0_fifo_intr_dropped_fault(struct nve0_fifo_priv *priv) -{ - u32 stat = nv_rd32(priv, 0x00259c); - nv_error(priv, "DROPPED_MMU_FAULT 0x%08x\n", stat); -} - -static void -nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit) -{ - u32 inst = nv_rd32(priv, 0x2800 + (unit * 0x10)); - u32 valo = nv_rd32(priv, 0x2804 + (unit * 0x10)); - u32 vahi = nv_rd32(priv, 0x2808 + (unit * 0x10)); - u32 stat = nv_rd32(priv, 0x280c + (unit * 0x10)); - u32 client = (stat & 0x00001f00) >> 8; - struct nouveau_engine *engine = NULL; - struct nouveau_object *engctx = NULL; - const struct nouveau_enum *en; - const char *name = "unknown"; - - nv_error(priv, "PFIFO: %s fault at 0x%010llx [", (stat & 0x00000080) ? - "write" : "read", (u64)vahi << 32 | valo); - nouveau_enum_print(nve0_fifo_fault_reason, stat & 0x0000000f); - pr_cont("] from "); - en = nouveau_enum_print(nve0_fifo_fault_engine, unit); - if (stat & 0x00000040) { - pr_cont("/"); - nouveau_enum_print(nve0_fifo_fault_hubclient, client); - } else { - pr_cont("/GPC%d/", (stat & 0x1f000000) >> 24); - nouveau_enum_print(nve0_fifo_fault_gpcclient, client); - } - - if (en && en->data2) { - if (en->data2 == NVDEV_SUBDEV_BAR) { - nv_mask(priv, 0x001704, 0x00000000, 0x00000000); - name = "BAR1"; - } else - if (en->data2 == NVDEV_SUBDEV_INSTMEM) { - nv_mask(priv, 0x001714, 0x00000000, 0x00000000); - name = "BAR3"; - } else { - engine = nouveau_engine(priv, en->data2); - if (engine) { - engctx = nouveau_engctx_get(engine, inst); - name = nouveau_client_name(engctx); - } - } - } - pr_cont(" on channel 0x%010llx [%s]\n", (u64)inst << 12, name); - - nouveau_engctx_put(engctx); -} - -static int -nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data) -{ - struct nve0_fifo_chan *chan = NULL; - struct nouveau_handle *bind; - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&priv->base.lock, flags); - if (likely(chid >= priv->base.min && chid <= priv->base.max)) - chan = (void *)priv->base.channel[chid]; - if (unlikely(!chan)) - goto out; - - bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e); - if (likely(bind)) { - if (!mthd || !nv_call(bind->object, mthd, data)) - ret = 0; - nouveau_namedb_put(bind); - } - -out: - spin_unlock_irqrestore(&priv->base.lock, flags); - return ret; -} - -static void nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit) { u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000)); @@ -647,6 +845,24 @@ nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit) } static void +nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv) +{ + u32 mask = nv_rd32(priv, 0x002a00); + while (mask) { + u32 engn = __ffs(mask); + wake_up(&priv->engine[engn].wait); + nv_wr32(priv, 0x002a00, 1 << engn); + mask &= ~(1 << engn); + } +} + +static void +nve0_fifo_intr_engine(struct nve0_fifo_priv *priv) +{ + nouveau_event_trigger(priv->base.uevent, 1, 0); +} + +static void nve0_fifo_intr(struct nouveau_subdev *subdev) { struct nve0_fifo_priv *priv = (void *)subdev; @@ -654,8 +870,7 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) u32 stat = nv_rd32(priv, 0x002100) & mask; if (stat & 0x00000001) { - u32 stat = nv_rd32(priv, 0x00252c); - nv_error(priv, "BIND_ERROR 0x%08x\n", stat); + nve0_fifo_intr_bind(priv); nv_wr32(priv, 0x002100, 0x00000001); stat &= ~0x00000001; } @@ -697,67 +912,54 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) } if (stat & 0x10000000) { - u32 units = nv_rd32(priv, 0x00259c); - u32 u = units; - - while (u) { - int i = ffs(u) - 1; - nve0_fifo_intr_fault(priv, i); - u &= ~(1 << i); + u32 mask = nv_rd32(priv, 0x00259c); + while (mask) { + u32 unit = __ffs(mask); + nve0_fifo_intr_fault(priv, unit); + nv_wr32(priv, 0x00259c, (1 << unit)); + mask &= ~(1 << unit); } - - nv_wr32(priv, 0x00259c, units); stat &= ~0x10000000; } if (stat & 0x20000000) { u32 mask = nv_rd32(priv, 0x0025a0); - u32 temp = mask; - - while (temp) { - u32 unit = ffs(temp) - 1; + while (mask) { + u32 unit = __ffs(mask); nve0_fifo_intr_pbdma(priv, unit); - temp &= ~(1 << unit); + nv_wr32(priv, 0x0025a0, (1 << unit)); + mask &= ~(1 << unit); } - - nv_wr32(priv, 0x0025a0, mask); stat &= ~0x20000000; } if (stat & 0x40000000) { - u32 mask = nv_mask(priv, 0x002a00, 0x00000000, 0x00000000); - - while (mask) { - u32 engn = ffs(mask) - 1; - /* runlist event, not currently used */ - mask &= ~(1 << engn); - } - + nve0_fifo_intr_runlist(priv); stat &= ~0x40000000; } if (stat & 0x80000000) { - nouveau_event_trigger(priv->base.uevent, 0); + nve0_fifo_intr_engine(priv); nv_wr32(priv, 0x002100, 0x80000000); stat &= ~0x80000000; } if (stat) { - nv_fatal(priv, "unhandled status 0x%08x\n", stat); + nv_error(priv, "INTR 0x%08x\n", stat); + nv_mask(priv, 0x002140, stat, 0x00000000); nv_wr32(priv, 0x002100, stat); - nv_wr32(priv, 0x002140, 0); } } static void -nve0_fifo_uevent_enable(struct nouveau_event *event, int index) +nve0_fifo_uevent_enable(struct nouveau_event *event, int type, int index) { struct nve0_fifo_priv *priv = event->priv; nv_mask(priv, 0x002140, 0x80000000, 0x80000000); } static void -nve0_fifo_uevent_disable(struct nouveau_event *event, int index) +nve0_fifo_uevent_disable(struct nouveau_event *event, int type, int index) { struct nve0_fifo_priv *priv = event->priv; nv_mask(priv, 0x002140, 0x80000000, 0x00000000); @@ -802,9 +1004,8 @@ nve0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12); - nv_wr32(priv, 0x002a00, 0xffffffff); nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0x3fffffff); + nv_wr32(priv, 0x002140, 0x7fffffff); return 0; } @@ -840,6 +1041,8 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; + INIT_WORK(&priv->fault, nve0_fifo_recover_work); + for (i = 0; i < FIFO_ENGINE_NR; i++) { ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000, 0, &priv->engine[i].runlist[0]); @@ -850,10 +1053,12 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 0, &priv->engine[i].runlist[1]); if (ret) return ret; + + init_waitqueue_head(&priv->engine[i].wait); } - ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem); + ret = nouveau_gpuobj_new(nv_object(priv), NULL, impl->channels * 0x200, + 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h index 014344ebee6..e96b32bb1bb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h @@ -8,6 +8,7 @@ int nve0_fifo_ctor(struct nouveau_object *, struct nouveau_object *, struct nouveau_object **); void nve0_fifo_dtor(struct nouveau_object *); int nve0_fifo_init(struct nouveau_object *); +int nve0_fifo_fini(struct nouveau_object *, bool); struct nve0_fifo_impl { struct nouveau_oclass base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c new file mode 100644 index 00000000000..224ee0287ab --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "ctxnvc0.h" + +static const struct nvc0_graph_pack +gk20a_grctx_pack_mthd[] = { + { nve4_grctx_init_a097_0, 0xa297 }, + { nvc0_grctx_init_902d_0, 0x902d }, + {} +}; + +struct nouveau_oclass * +gk20a_grctx_oclass = &(struct nvc0_grctx_oclass) { + .base.handle = NV_ENGCTX(GR, 0xea), + .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, + .mods = nve4_grctx_generate_mods, + .unkn = nve4_grctx_generate_unkn, + .hub = nve4_grctx_pack_hub, + .gpc = nve4_grctx_pack_gpc, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nve4_grctx_pack_tpc, + .ppc = nve4_grctx_pack_ppc, + .icmd = nve4_grctx_pack_icmd, + .mthd = gk20a_grctx_pack_mthd, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c new file mode 100644 index 00000000000..b0d0fb2f4d0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c @@ -0,0 +1,991 @@ +/* + * 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 +gm107_grctx_init_icmd_0[] = { + { 0x001000, 1, 0x01, 0x00000004 }, + { 0x000039, 3, 0x01, 0x00000000 }, + { 0x0000a9, 1, 0x01, 0x0000ffff }, + { 0x000038, 1, 0x01, 0x0fac6881 }, + { 0x00003d, 1, 0x01, 0x00000001 }, + { 0x0000e8, 8, 0x01, 0x00000400 }, + { 0x000078, 8, 0x01, 0x00000300 }, + { 0x000050, 1, 0x01, 0x00000011 }, + { 0x000058, 8, 0x01, 0x00000008 }, + { 0x000208, 8, 0x01, 0x00000001 }, + { 0x000081, 1, 0x01, 0x00000001 }, + { 0x000085, 1, 0x01, 0x00000004 }, + { 0x000088, 1, 0x01, 0x00000400 }, + { 0x000090, 1, 0x01, 0x00000300 }, + { 0x000098, 1, 0x01, 0x00001001 }, + { 0x0000e3, 1, 0x01, 0x00000001 }, + { 0x0000da, 1, 0x01, 0x00000001 }, + { 0x0000f8, 1, 0x01, 0x00000003 }, + { 0x0000fa, 1, 0x01, 0x00000001 }, + { 0x0000b1, 2, 0x01, 0x00000001 }, + { 0x00009f, 4, 0x01, 0x0000ffff }, + { 0x0000a8, 1, 0x01, 0x0000ffff }, + { 0x0000ad, 1, 0x01, 0x0000013e }, + { 0x0000e1, 1, 0x01, 0x00000010 }, + { 0x000290, 16, 0x01, 0x00000000 }, + { 0x0003b0, 16, 0x01, 0x00000000 }, + { 0x0002a0, 16, 0x01, 0x00000000 }, + { 0x000420, 16, 0x01, 0x00000000 }, + { 0x0002b0, 16, 0x01, 0x00000000 }, + { 0x000430, 16, 0x01, 0x00000000 }, + { 0x0002c0, 16, 0x01, 0x00000000 }, + { 0x0004d0, 16, 0x01, 0x00000000 }, + { 0x000720, 16, 0x01, 0x00000000 }, + { 0x0008c0, 16, 0x01, 0x00000000 }, + { 0x000890, 16, 0x01, 0x00000000 }, + { 0x0008e0, 16, 0x01, 0x00000000 }, + { 0x0008a0, 16, 0x01, 0x00000000 }, + { 0x0008f0, 16, 0x01, 0x00000000 }, + { 0x00094c, 1, 0x01, 0x000000ff }, + { 0x00094d, 1, 0x01, 0xffffffff }, + { 0x00094e, 1, 0x01, 0x00000002 }, + { 0x0002f2, 2, 0x01, 0x00000001 }, + { 0x0002f5, 1, 0x01, 0x00000001 }, + { 0x0002f7, 1, 0x01, 0x00000001 }, + { 0x000303, 1, 0x01, 0x00000001 }, + { 0x0002e6, 1, 0x01, 0x00000001 }, + { 0x000466, 1, 0x01, 0x00000052 }, + { 0x000301, 1, 0x01, 0x3f800000 }, + { 0x000304, 1, 0x01, 0x30201000 }, + { 0x000305, 1, 0x01, 0x70605040 }, + { 0x000306, 1, 0x01, 0xb8a89888 }, + { 0x000307, 1, 0x01, 0xf8e8d8c8 }, + { 0x00030a, 1, 0x01, 0x00ffff00 }, + { 0x0000de, 1, 0x01, 0x00000001 }, + { 0x00030b, 1, 0x01, 0x0000001a }, + { 0x00030c, 1, 0x01, 0x00000001 }, + { 0x000318, 1, 0x01, 0x00000001 }, + { 0x000340, 1, 0x01, 0x00000000 }, + { 0x00037d, 1, 0x01, 0x00000006 }, + { 0x0003a0, 1, 0x01, 0x00000002 }, + { 0x0003aa, 1, 0x01, 0x00000001 }, + { 0x0003a9, 1, 0x01, 0x00000001 }, + { 0x000380, 1, 0x01, 0x00000001 }, + { 0x000383, 1, 0x01, 0x00000011 }, + { 0x000360, 1, 0x01, 0x00000040 }, + { 0x000366, 2, 0x01, 0x00000000 }, + { 0x000368, 1, 0x01, 0x00000fff }, + { 0x000370, 2, 0x01, 0x00000000 }, + { 0x000372, 1, 0x01, 0x000fffff }, + { 0x00037a, 1, 0x01, 0x00000012 }, + { 0x000619, 1, 0x01, 0x00000003 }, + { 0x000811, 1, 0x01, 0x00000003 }, + { 0x000812, 1, 0x01, 0x00000004 }, + { 0x000813, 1, 0x01, 0x00000006 }, + { 0x000814, 1, 0x01, 0x00000008 }, + { 0x000815, 1, 0x01, 0x0000000b }, + { 0x000800, 6, 0x01, 0x00000001 }, + { 0x000632, 1, 0x01, 0x00000001 }, + { 0x000633, 1, 0x01, 0x00000002 }, + { 0x000634, 1, 0x01, 0x00000003 }, + { 0x000635, 1, 0x01, 0x00000004 }, + { 0x000654, 1, 0x01, 0x3f800000 }, + { 0x000657, 1, 0x01, 0x3f800000 }, + { 0x000655, 2, 0x01, 0x3f800000 }, + { 0x0006cd, 1, 0x01, 0x3f800000 }, + { 0x0007f5, 1, 0x01, 0x3f800000 }, + { 0x0007dc, 1, 0x01, 0x39291909 }, + { 0x0007dd, 1, 0x01, 0x79695949 }, + { 0x0007de, 1, 0x01, 0xb9a99989 }, + { 0x0007df, 1, 0x01, 0xf9e9d9c9 }, + { 0x0007e8, 1, 0x01, 0x00003210 }, + { 0x0007e9, 1, 0x01, 0x00007654 }, + { 0x0007ea, 1, 0x01, 0x00000098 }, + { 0x0007ec, 1, 0x01, 0x39291909 }, + { 0x0007ed, 1, 0x01, 0x79695949 }, + { 0x0007ee, 1, 0x01, 0xb9a99989 }, + { 0x0007ef, 1, 0x01, 0xf9e9d9c9 }, + { 0x0007f0, 1, 0x01, 0x00003210 }, + { 0x0007f1, 1, 0x01, 0x00007654 }, + { 0x0007f2, 1, 0x01, 0x00000098 }, + { 0x0005a5, 1, 0x01, 0x00000001 }, + { 0x0005d0, 1, 0x01, 0x20181008 }, + { 0x0005d1, 1, 0x01, 0x40383028 }, + { 0x0005d2, 1, 0x01, 0x60585048 }, + { 0x0005d3, 1, 0x01, 0x80787068 }, + { 0x000980, 128, 0x01, 0x00000000 }, + { 0x000468, 1, 0x01, 0x00000004 }, + { 0x00046c, 1, 0x01, 0x00000001 }, + { 0x000470, 96, 0x01, 0x00000000 }, + { 0x000510, 16, 0x01, 0x3f800000 }, + { 0x000520, 1, 0x01, 0x000002b6 }, + { 0x000529, 1, 0x01, 0x00000001 }, + { 0x000530, 16, 0x01, 0xffff0000 }, + { 0x000550, 32, 0x01, 0xffff0000 }, + { 0x000585, 1, 0x01, 0x0000003f }, + { 0x000576, 1, 0x01, 0x00000003 }, + { 0x00057b, 1, 0x01, 0x00000059 }, + { 0x000586, 1, 0x01, 0x00000040 }, + { 0x000582, 2, 0x01, 0x00000080 }, + { 0x000595, 1, 0x01, 0x00400040 }, + { 0x000596, 1, 0x01, 0x00000492 }, + { 0x000597, 1, 0x01, 0x08080203 }, + { 0x0005ad, 1, 0x01, 0x00000008 }, + { 0x000598, 1, 0x01, 0x00020001 }, + { 0x0005c2, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, + { 0x00063a, 1, 0x01, 0x00000002 }, + { 0x00063b, 2, 0x01, 0x00000001 }, + { 0x00063d, 1, 0x01, 0x00000002 }, + { 0x00063e, 1, 0x01, 0x00000001 }, + { 0x0008b8, 8, 0x01, 0x00000001 }, + { 0x000900, 8, 0x01, 0x00000001 }, + { 0x000908, 8, 0x01, 0x00000002 }, + { 0x000910, 16, 0x01, 0x00000001 }, + { 0x000920, 8, 0x01, 0x00000002 }, + { 0x000928, 8, 0x01, 0x00000001 }, + { 0x000662, 1, 0x01, 0x00000001 }, + { 0x000648, 9, 0x01, 0x00000001 }, + { 0x000658, 1, 0x01, 0x0000000f }, + { 0x0007ff, 1, 0x01, 0x0000000a }, + { 0x00066a, 1, 0x01, 0x40000000 }, + { 0x00066b, 1, 0x01, 0x10000000 }, + { 0x00066c, 2, 0x01, 0xffff0000 }, + { 0x0007af, 2, 0x01, 0x00000008 }, + { 0x0007f6, 1, 0x01, 0x00000001 }, + { 0x0006b2, 1, 0x01, 0x00000055 }, + { 0x0007ad, 1, 0x01, 0x00000003 }, + { 0x000971, 1, 0x01, 0x00000008 }, + { 0x000972, 1, 0x01, 0x00000040 }, + { 0x000973, 1, 0x01, 0x0000012c }, + { 0x00097c, 1, 0x01, 0x00000040 }, + { 0x000975, 1, 0x01, 0x00000020 }, + { 0x000976, 1, 0x01, 0x00000001 }, + { 0x000977, 1, 0x01, 0x00000020 }, + { 0x000978, 1, 0x01, 0x00000001 }, + { 0x000957, 1, 0x01, 0x00000003 }, + { 0x00095e, 1, 0x01, 0x20164010 }, + { 0x00095f, 1, 0x01, 0x00000020 }, + { 0x000a0d, 1, 0x01, 0x00000006 }, + { 0x00097d, 1, 0x01, 0x0000000c }, + { 0x000683, 1, 0x01, 0x00000006 }, + { 0x000687, 1, 0x01, 0x003fffff }, + { 0x0006a0, 1, 0x01, 0x00000005 }, + { 0x000840, 1, 0x01, 0x00400008 }, + { 0x000841, 1, 0x01, 0x08000080 }, + { 0x000842, 1, 0x01, 0x00400008 }, + { 0x000843, 1, 0x01, 0x08000080 }, + { 0x000818, 8, 0x01, 0x00000000 }, + { 0x000848, 16, 0x01, 0x00000000 }, + { 0x000738, 1, 0x01, 0x00000000 }, + { 0x0006aa, 1, 0x01, 0x00000001 }, + { 0x0006ab, 1, 0x01, 0x00000002 }, + { 0x0006ac, 1, 0x01, 0x00000080 }, + { 0x0006ad, 2, 0x01, 0x00000100 }, + { 0x0006b1, 1, 0x01, 0x00000011 }, + { 0x0006bb, 1, 0x01, 0x000000cf }, + { 0x0006ce, 1, 0x01, 0x2a712488 }, + { 0x000739, 1, 0x01, 0x4085c000 }, + { 0x00073a, 1, 0x01, 0x00000080 }, + { 0x000786, 1, 0x01, 0x80000100 }, + { 0x00073c, 1, 0x01, 0x00010100 }, + { 0x00073d, 1, 0x01, 0x02800000 }, + { 0x000787, 1, 0x01, 0x000000cf }, + { 0x00078c, 1, 0x01, 0x00000008 }, + { 0x000792, 1, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, + { 0x000797, 1, 0x01, 0x000000cf }, + { 0x000836, 1, 0x01, 0x00000001 }, + { 0x00079a, 1, 0x01, 0x00000002 }, + { 0x000833, 1, 0x01, 0x04444480 }, + { 0x0007a1, 1, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, + { 0x000831, 1, 0x01, 0x00000004 }, + { 0x000b07, 1, 0x01, 0x00000002 }, + { 0x000b08, 2, 0x01, 0x00000100 }, + { 0x000b0a, 1, 0x01, 0x00000001 }, + { 0x000a04, 1, 0x01, 0x000000ff }, + { 0x000a0b, 1, 0x01, 0x00000040 }, + { 0x00097f, 1, 0x01, 0x00000100 }, + { 0x000a02, 1, 0x01, 0x00000001 }, + { 0x000809, 1, 0x01, 0x00000007 }, + { 0x00c221, 1, 0x01, 0x00000040 }, + { 0x00c1b0, 8, 0x01, 0x0000000f }, + { 0x00c1b8, 1, 0x01, 0x0fac6881 }, + { 0x00c1b9, 1, 0x01, 0x00fac688 }, + { 0x00c401, 1, 0x01, 0x00000001 }, + { 0x00c402, 1, 0x01, 0x00010001 }, + { 0x00c403, 2, 0x01, 0x00000001 }, + { 0x00c40e, 1, 0x01, 0x00000020 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + { 0x001000, 1, 0x01, 0x00000002 }, + { 0x0006aa, 1, 0x01, 0x00000001 }, + { 0x0006ad, 2, 0x01, 0x00000100 }, + { 0x0006b1, 1, 0x01, 0x00000011 }, + { 0x00078c, 1, 0x01, 0x00000008 }, + { 0x000792, 1, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, + { 0x000797, 1, 0x01, 0x000000cf }, + { 0x00079a, 1, 0x01, 0x00000002 }, + { 0x0007a1, 1, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, + { 0x000831, 1, 0x01, 0x00000004 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + { 0x001000, 1, 0x01, 0x00000008 }, + { 0x000039, 3, 0x01, 0x00000000 }, + { 0x000380, 1, 0x01, 0x00000001 }, + { 0x000366, 2, 0x01, 0x00000000 }, + { 0x000368, 1, 0x01, 0x00000fff }, + { 0x000370, 2, 0x01, 0x00000000 }, + { 0x000372, 1, 0x01, 0x000fffff }, + { 0x000813, 1, 0x01, 0x00000006 }, + { 0x000814, 1, 0x01, 0x00000008 }, + { 0x000818, 8, 0x01, 0x00000000 }, + { 0x000848, 16, 0x01, 0x00000000 }, + { 0x000738, 1, 0x01, 0x00000000 }, + { 0x000b07, 1, 0x01, 0x00000002 }, + { 0x000b08, 2, 0x01, 0x00000100 }, + { 0x000b0a, 1, 0x01, 0x00000001 }, + { 0x000a04, 1, 0x01, 0x000000ff }, + { 0x000a0b, 1, 0x01, 0x00000040 }, + { 0x00097f, 1, 0x01, 0x00000100 }, + { 0x000a02, 1, 0x01, 0x00000001 }, + { 0x000809, 1, 0x01, 0x00000007 }, + { 0x00c221, 1, 0x01, 0x00000040 }, + { 0x00c401, 1, 0x01, 0x00000001 }, + { 0x00c402, 1, 0x01, 0x00010001 }, + { 0x00c403, 2, 0x01, 0x00000001 }, + { 0x00c40e, 1, 0x01, 0x00000020 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + { 0x001000, 1, 0x01, 0x00000001 }, + { 0x000b07, 1, 0x01, 0x00000002 }, + { 0x000b08, 2, 0x01, 0x00000100 }, + { 0x000b0a, 1, 0x01, 0x00000001 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + {} +}; + +static const struct nvc0_graph_pack +gm107_grctx_pack_icmd[] = { + { gm107_grctx_init_icmd_0 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_b097_0[] = { + { 0x000800, 8, 0x40, 0x00000000 }, + { 0x000804, 8, 0x40, 0x00000000 }, + { 0x000808, 8, 0x40, 0x00000400 }, + { 0x00080c, 8, 0x40, 0x00000300 }, + { 0x000810, 1, 0x04, 0x000000cf }, + { 0x000850, 7, 0x40, 0x00000000 }, + { 0x000814, 8, 0x40, 0x00000040 }, + { 0x000818, 8, 0x40, 0x00000001 }, + { 0x00081c, 8, 0x40, 0x00000000 }, + { 0x000820, 8, 0x40, 0x00000000 }, + { 0x001c00, 16, 0x10, 0x00000000 }, + { 0x001c04, 16, 0x10, 0x00000000 }, + { 0x001c08, 16, 0x10, 0x00000000 }, + { 0x001c0c, 16, 0x10, 0x00000000 }, + { 0x001d00, 16, 0x10, 0x00000000 }, + { 0x001d04, 16, 0x10, 0x00000000 }, + { 0x001d08, 16, 0x10, 0x00000000 }, + { 0x001d0c, 16, 0x10, 0x00000000 }, + { 0x001f00, 16, 0x08, 0x00000000 }, + { 0x001f04, 16, 0x08, 0x00000000 }, + { 0x001f80, 16, 0x08, 0x00000000 }, + { 0x001f84, 16, 0x08, 0x00000000 }, + { 0x002000, 1, 0x04, 0x00000000 }, + { 0x002040, 1, 0x04, 0x00000011 }, + { 0x002080, 1, 0x04, 0x00000020 }, + { 0x0020c0, 1, 0x04, 0x00000030 }, + { 0x002100, 1, 0x04, 0x00000040 }, + { 0x002140, 1, 0x04, 0x00000051 }, + { 0x00200c, 6, 0x40, 0x00000001 }, + { 0x002010, 1, 0x04, 0x00000000 }, + { 0x002050, 1, 0x04, 0x00000000 }, + { 0x002090, 1, 0x04, 0x00000001 }, + { 0x0020d0, 1, 0x04, 0x00000002 }, + { 0x002110, 1, 0x04, 0x00000003 }, + { 0x002150, 1, 0x04, 0x00000004 }, + { 0x000380, 4, 0x20, 0x00000000 }, + { 0x000384, 4, 0x20, 0x00000000 }, + { 0x000388, 4, 0x20, 0x00000000 }, + { 0x00038c, 4, 0x20, 0x00000000 }, + { 0x000700, 4, 0x10, 0x00000000 }, + { 0x000704, 4, 0x10, 0x00000000 }, + { 0x000708, 4, 0x10, 0x00000000 }, + { 0x002800, 128, 0x04, 0x00000000 }, + { 0x000a00, 16, 0x20, 0x00000000 }, + { 0x000a04, 16, 0x20, 0x00000000 }, + { 0x000a08, 16, 0x20, 0x00000000 }, + { 0x000a0c, 16, 0x20, 0x00000000 }, + { 0x000a10, 16, 0x20, 0x00000000 }, + { 0x000a14, 16, 0x20, 0x00000000 }, + { 0x000c00, 16, 0x10, 0x00000000 }, + { 0x000c04, 16, 0x10, 0x00000000 }, + { 0x000c08, 16, 0x10, 0x00000000 }, + { 0x000c0c, 16, 0x10, 0x3f800000 }, + { 0x000d00, 8, 0x08, 0xffff0000 }, + { 0x000d04, 8, 0x08, 0xffff0000 }, + { 0x000e00, 16, 0x10, 0x00000000 }, + { 0x000e04, 16, 0x10, 0xffff0000 }, + { 0x000e08, 16, 0x10, 0xffff0000 }, + { 0x000d40, 4, 0x08, 0x00000000 }, + { 0x000d44, 4, 0x08, 0x00000000 }, + { 0x001e00, 8, 0x20, 0x00000001 }, + { 0x001e04, 8, 0x20, 0x00000001 }, + { 0x001e08, 8, 0x20, 0x00000002 }, + { 0x001e0c, 8, 0x20, 0x00000001 }, + { 0x001e10, 8, 0x20, 0x00000001 }, + { 0x001e14, 8, 0x20, 0x00000002 }, + { 0x001e18, 8, 0x20, 0x00000001 }, + { 0x001480, 8, 0x10, 0x00000000 }, + { 0x001484, 8, 0x10, 0x00000000 }, + { 0x001488, 8, 0x10, 0x00000000 }, + { 0x003400, 128, 0x04, 0x00000000 }, + { 0x00030c, 1, 0x04, 0x00000001 }, + { 0x001944, 1, 0x04, 0x00000000 }, + { 0x001514, 1, 0x04, 0x00000000 }, + { 0x000d68, 1, 0x04, 0x0000ffff }, + { 0x00121c, 1, 0x04, 0x0fac6881 }, + { 0x000fac, 1, 0x04, 0x00000001 }, + { 0x001538, 1, 0x04, 0x00000001 }, + { 0x000fe0, 2, 0x04, 0x00000000 }, + { 0x000fe8, 1, 0x04, 0x00000014 }, + { 0x000fec, 1, 0x04, 0x00000040 }, + { 0x000ff0, 1, 0x04, 0x00000000 }, + { 0x00179c, 1, 0x04, 0x00000000 }, + { 0x001228, 1, 0x04, 0x00000400 }, + { 0x00122c, 1, 0x04, 0x00000300 }, + { 0x001230, 1, 0x04, 0x00010001 }, + { 0x0007f8, 1, 0x04, 0x00000000 }, + { 0x0015b4, 1, 0x04, 0x00000001 }, + { 0x0015cc, 1, 0x04, 0x00000000 }, + { 0x001534, 1, 0x04, 0x00000000 }, + { 0x000754, 1, 0x04, 0x00000001 }, + { 0x000fb0, 1, 0x04, 0x00000000 }, + { 0x0015d0, 1, 0x04, 0x00000000 }, + { 0x00153c, 1, 0x04, 0x00000000 }, + { 0x0016b4, 1, 0x04, 0x00000003 }, + { 0x000fbc, 4, 0x04, 0x0000ffff }, + { 0x000df8, 2, 0x04, 0x00000000 }, + { 0x001948, 1, 0x04, 0x00000000 }, + { 0x001970, 1, 0x04, 0x00000001 }, + { 0x00161c, 1, 0x04, 0x000009f0 }, + { 0x000dcc, 1, 0x04, 0x00000010 }, + { 0x0015e4, 1, 0x04, 0x00000000 }, + { 0x001160, 32, 0x04, 0x25e00040 }, + { 0x001880, 32, 0x04, 0x00000000 }, + { 0x000f84, 2, 0x04, 0x00000000 }, + { 0x0017c8, 2, 0x04, 0x00000000 }, + { 0x0017d0, 1, 0x04, 0x000000ff }, + { 0x0017d4, 1, 0x04, 0xffffffff }, + { 0x0017d8, 1, 0x04, 0x00000002 }, + { 0x0017dc, 1, 0x04, 0x00000000 }, + { 0x0015f4, 2, 0x04, 0x00000000 }, + { 0x001434, 2, 0x04, 0x00000000 }, + { 0x000d74, 1, 0x04, 0x00000000 }, + { 0x0013a4, 1, 0x04, 0x00000000 }, + { 0x001318, 1, 0x04, 0x00000001 }, + { 0x001080, 2, 0x04, 0x00000000 }, + { 0x001088, 2, 0x04, 0x00000001 }, + { 0x001090, 1, 0x04, 0x00000000 }, + { 0x001094, 1, 0x04, 0x00000001 }, + { 0x001098, 1, 0x04, 0x00000000 }, + { 0x00109c, 1, 0x04, 0x00000001 }, + { 0x0010a0, 2, 0x04, 0x00000000 }, + { 0x001644, 1, 0x04, 0x00000000 }, + { 0x000748, 1, 0x04, 0x00000000 }, + { 0x000de8, 1, 0x04, 0x00000000 }, + { 0x001648, 1, 0x04, 0x00000000 }, + { 0x0012a4, 1, 0x04, 0x00000000 }, + { 0x001120, 4, 0x04, 0x00000000 }, + { 0x001118, 1, 0x04, 0x00000000 }, + { 0x00164c, 1, 0x04, 0x00000000 }, + { 0x001658, 1, 0x04, 0x00000000 }, + { 0x001910, 1, 0x04, 0x00000290 }, + { 0x001518, 1, 0x04, 0x00000000 }, + { 0x00165c, 1, 0x04, 0x00000001 }, + { 0x001520, 1, 0x04, 0x00000000 }, + { 0x001604, 1, 0x04, 0x00000000 }, + { 0x001570, 1, 0x04, 0x00000000 }, + { 0x0013b0, 2, 0x04, 0x3f800000 }, + { 0x00020c, 1, 0x04, 0x00000000 }, + { 0x001670, 1, 0x04, 0x30201000 }, + { 0x001674, 1, 0x04, 0x70605040 }, + { 0x001678, 1, 0x04, 0xb8a89888 }, + { 0x00167c, 1, 0x04, 0xf8e8d8c8 }, + { 0x00166c, 1, 0x04, 0x00000000 }, + { 0x001680, 1, 0x04, 0x00ffff00 }, + { 0x0012d0, 1, 0x04, 0x00000003 }, + { 0x0012d4, 1, 0x04, 0x00000002 }, + { 0x001684, 2, 0x04, 0x00000000 }, + { 0x000dac, 2, 0x04, 0x00001b02 }, + { 0x000db4, 1, 0x04, 0x00000000 }, + { 0x00168c, 1, 0x04, 0x00000000 }, + { 0x0015bc, 1, 0x04, 0x00000000 }, + { 0x00156c, 1, 0x04, 0x00000000 }, + { 0x00187c, 1, 0x04, 0x00000000 }, + { 0x001110, 1, 0x04, 0x00000001 }, + { 0x000dc0, 3, 0x04, 0x00000000 }, + { 0x000f40, 5, 0x04, 0x00000000 }, + { 0x001234, 1, 0x04, 0x00000000 }, + { 0x001690, 1, 0x04, 0x00000000 }, + { 0x000790, 5, 0x04, 0x00000000 }, + { 0x00077c, 1, 0x04, 0x00000000 }, + { 0x001000, 1, 0x04, 0x00000010 }, + { 0x0010fc, 1, 0x04, 0x00000000 }, + { 0x001290, 1, 0x04, 0x00000000 }, + { 0x000218, 1, 0x04, 0x00000010 }, + { 0x0012d8, 1, 0x04, 0x00000000 }, + { 0x0012dc, 1, 0x04, 0x00000010 }, + { 0x000d94, 1, 0x04, 0x00000001 }, + { 0x00155c, 2, 0x04, 0x00000000 }, + { 0x001564, 1, 0x04, 0x00000fff }, + { 0x001574, 2, 0x04, 0x00000000 }, + { 0x00157c, 1, 0x04, 0x000fffff }, + { 0x001354, 1, 0x04, 0x00000000 }, + { 0x001610, 1, 0x04, 0x00000012 }, + { 0x001608, 2, 0x04, 0x00000000 }, + { 0x00260c, 1, 0x04, 0x00000000 }, + { 0x0007ac, 1, 0x04, 0x00000000 }, + { 0x00162c, 1, 0x04, 0x00000003 }, + { 0x000210, 1, 0x04, 0x00000000 }, + { 0x000320, 1, 0x04, 0x00000000 }, + { 0x000324, 6, 0x04, 0x3f800000 }, + { 0x000750, 1, 0x04, 0x00000000 }, + { 0x000760, 1, 0x04, 0x39291909 }, + { 0x000764, 1, 0x04, 0x79695949 }, + { 0x000768, 1, 0x04, 0xb9a99989 }, + { 0x00076c, 1, 0x04, 0xf9e9d9c9 }, + { 0x000770, 1, 0x04, 0x30201000 }, + { 0x000774, 1, 0x04, 0x70605040 }, + { 0x000778, 1, 0x04, 0x00009080 }, + { 0x000780, 1, 0x04, 0x39291909 }, + { 0x000784, 1, 0x04, 0x79695949 }, + { 0x000788, 1, 0x04, 0xb9a99989 }, + { 0x00078c, 1, 0x04, 0xf9e9d9c9 }, + { 0x0007d0, 1, 0x04, 0x30201000 }, + { 0x0007d4, 1, 0x04, 0x70605040 }, + { 0x0007d8, 1, 0x04, 0x00009080 }, + { 0x00037c, 1, 0x04, 0x00000001 }, + { 0x000740, 2, 0x04, 0x00000000 }, + { 0x002600, 1, 0x04, 0x00000000 }, + { 0x001918, 1, 0x04, 0x00000000 }, + { 0x00191c, 1, 0x04, 0x00000900 }, + { 0x001920, 1, 0x04, 0x00000405 }, + { 0x001308, 1, 0x04, 0x00000001 }, + { 0x001924, 1, 0x04, 0x00000000 }, + { 0x0013ac, 1, 0x04, 0x00000000 }, + { 0x00192c, 1, 0x04, 0x00000001 }, + { 0x00193c, 1, 0x04, 0x00002c1c }, + { 0x000d7c, 1, 0x04, 0x00000000 }, + { 0x000f8c, 1, 0x04, 0x00000000 }, + { 0x0002c0, 1, 0x04, 0x00000001 }, + { 0x001510, 1, 0x04, 0x00000000 }, + { 0x001940, 1, 0x04, 0x00000000 }, + { 0x000ff4, 2, 0x04, 0x00000000 }, + { 0x00194c, 2, 0x04, 0x00000000 }, + { 0x001968, 1, 0x04, 0x00000000 }, + { 0x001590, 1, 0x04, 0x0000003f }, + { 0x0007e8, 4, 0x04, 0x00000000 }, + { 0x00196c, 1, 0x04, 0x00000011 }, + { 0x0002e4, 1, 0x04, 0x0000b001 }, + { 0x00036c, 2, 0x04, 0x00000000 }, + { 0x00197c, 1, 0x04, 0x00000000 }, + { 0x000fcc, 2, 0x04, 0x00000000 }, + { 0x0002d8, 1, 0x04, 0x00000040 }, + { 0x001980, 1, 0x04, 0x00000080 }, + { 0x001504, 1, 0x04, 0x00000080 }, + { 0x001984, 1, 0x04, 0x00000000 }, + { 0x000f60, 1, 0x04, 0x00000000 }, + { 0x000f64, 1, 0x04, 0x00400040 }, + { 0x000f68, 1, 0x04, 0x00002212 }, + { 0x000f6c, 1, 0x04, 0x08080203 }, + { 0x001108, 1, 0x04, 0x00000008 }, + { 0x000f70, 1, 0x04, 0x00080001 }, + { 0x000ffc, 1, 0x04, 0x00000000 }, + { 0x000300, 1, 0x04, 0x00000001 }, + { 0x0013a8, 1, 0x04, 0x00000000 }, + { 0x0012ec, 1, 0x04, 0x00000000 }, + { 0x001310, 1, 0x04, 0x00000000 }, + { 0x001314, 1, 0x04, 0x00000001 }, + { 0x001380, 1, 0x04, 0x00000000 }, + { 0x001384, 4, 0x04, 0x00000001 }, + { 0x001394, 1, 0x04, 0x00000000 }, + { 0x00139c, 1, 0x04, 0x00000000 }, + { 0x001398, 1, 0x04, 0x00000000 }, + { 0x001594, 1, 0x04, 0x00000000 }, + { 0x001598, 4, 0x04, 0x00000001 }, + { 0x000f54, 3, 0x04, 0x00000000 }, + { 0x0019bc, 1, 0x04, 0x00000000 }, + { 0x000f9c, 2, 0x04, 0x00000000 }, + { 0x0012cc, 1, 0x04, 0x00000000 }, + { 0x0012e8, 1, 0x04, 0x00000000 }, + { 0x00130c, 1, 0x04, 0x00000001 }, + { 0x001360, 8, 0x04, 0x00000000 }, + { 0x00133c, 2, 0x04, 0x00000001 }, + { 0x001344, 1, 0x04, 0x00000002 }, + { 0x001348, 2, 0x04, 0x00000001 }, + { 0x001350, 1, 0x04, 0x00000002 }, + { 0x001358, 1, 0x04, 0x00000001 }, + { 0x0012e4, 1, 0x04, 0x00000000 }, + { 0x00131c, 4, 0x04, 0x00000000 }, + { 0x0019c0, 1, 0x04, 0x00000000 }, + { 0x001140, 1, 0x04, 0x00000000 }, + { 0x000dd0, 1, 0x04, 0x00000000 }, + { 0x000dd4, 1, 0x04, 0x00000001 }, + { 0x0002f4, 1, 0x04, 0x00000000 }, + { 0x0019c4, 1, 0x04, 0x00000000 }, + { 0x0019c8, 1, 0x04, 0x00001500 }, + { 0x00135c, 1, 0x04, 0x00000000 }, + { 0x000f90, 1, 0x04, 0x00000000 }, + { 0x0019e0, 8, 0x04, 0x00000001 }, + { 0x0019cc, 1, 0x04, 0x00000001 }, + { 0x0015b8, 1, 0x04, 0x00000000 }, + { 0x001a00, 1, 0x04, 0x00001111 }, + { 0x001a04, 7, 0x04, 0x00000000 }, + { 0x000d6c, 2, 0x04, 0xffff0000 }, + { 0x0010f8, 1, 0x04, 0x00001010 }, + { 0x000d80, 5, 0x04, 0x00000000 }, + { 0x000da0, 1, 0x04, 0x00000000 }, + { 0x0007a4, 2, 0x04, 0x00000000 }, + { 0x001508, 1, 0x04, 0x80000000 }, + { 0x00150c, 1, 0x04, 0x40000000 }, + { 0x001668, 1, 0x04, 0x00000000 }, + { 0x000318, 2, 0x04, 0x00000008 }, + { 0x000d9c, 1, 0x04, 0x00000001 }, + { 0x000f14, 1, 0x04, 0x00000000 }, + { 0x000374, 1, 0x04, 0x00000000 }, + { 0x000378, 1, 0x04, 0x0000000c }, + { 0x0007dc, 1, 0x04, 0x00000000 }, + { 0x00074c, 1, 0x04, 0x00000055 }, + { 0x001420, 1, 0x04, 0x00000003 }, + { 0x001008, 1, 0x04, 0x00000008 }, + { 0x00100c, 1, 0x04, 0x00000040 }, + { 0x001010, 1, 0x04, 0x0000012c }, + { 0x000d60, 1, 0x04, 0x00000040 }, + { 0x001018, 1, 0x04, 0x00000020 }, + { 0x00101c, 1, 0x04, 0x00000001 }, + { 0x001020, 1, 0x04, 0x00000020 }, + { 0x001024, 1, 0x04, 0x00000001 }, + { 0x001444, 3, 0x04, 0x00000000 }, + { 0x000360, 1, 0x04, 0x20164010 }, + { 0x000364, 1, 0x04, 0x00000020 }, + { 0x000368, 1, 0x04, 0x00000000 }, + { 0x000da8, 1, 0x04, 0x00000030 }, + { 0x000de4, 1, 0x04, 0x00000000 }, + { 0x000204, 1, 0x04, 0x00000006 }, + { 0x0002d0, 1, 0x04, 0x003fffff }, + { 0x001220, 1, 0x04, 0x00000005 }, + { 0x000fdc, 1, 0x04, 0x00000000 }, + { 0x000f98, 1, 0x04, 0x00400008 }, + { 0x001284, 1, 0x04, 0x08000080 }, + { 0x001450, 1, 0x04, 0x00400008 }, + { 0x001454, 1, 0x04, 0x08000080 }, + { 0x000214, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +gm107_grctx_pack_mthd[] = { + { gm107_grctx_init_b097_0, 0xb097 }, + { nvc0_grctx_init_902d_0, 0x902d }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_fe_0[] = { + { 0x404004, 8, 0x04, 0x00000000 }, + { 0x404024, 1, 0x04, 0x0000e000 }, + { 0x404028, 8, 0x04, 0x00000000 }, + { 0x4040a8, 8, 0x04, 0x00000000 }, + { 0x4040c8, 1, 0x04, 0xf800008f }, + { 0x4040d0, 6, 0x04, 0x00000000 }, + { 0x4040f8, 1, 0x04, 0x00000000 }, + { 0x404100, 10, 0x04, 0x00000000 }, + { 0x404130, 2, 0x04, 0x00000000 }, + { 0x404150, 1, 0x04, 0x0000002e }, + { 0x404154, 1, 0x04, 0x00000400 }, + { 0x404158, 1, 0x04, 0x00000200 }, + { 0x404164, 1, 0x04, 0x00000045 }, + { 0x40417c, 2, 0x04, 0x00000000 }, + { 0x404194, 1, 0x04, 0x01000700 }, + { 0x4041a0, 4, 0x04, 0x00000000 }, + { 0x404200, 4, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_ds_0[] = { + { 0x405800, 1, 0x04, 0x0f8001bf }, + { 0x405830, 1, 0x04, 0x0aa01000 }, + { 0x405834, 1, 0x04, 0x08000000 }, + { 0x405838, 1, 0x04, 0x00000000 }, + { 0x405854, 1, 0x04, 0x00000000 }, + { 0x405870, 4, 0x04, 0x00000001 }, + { 0x405a00, 2, 0x04, 0x00000000 }, + { 0x405a18, 1, 0x04, 0x00000000 }, + { 0x405a1c, 1, 0x04, 0x000000ff }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_pd_0[] = { + { 0x406020, 1, 0x04, 0x07410001 }, + { 0x406028, 4, 0x04, 0x00000001 }, + { 0x4064a8, 1, 0x04, 0x00000000 }, + { 0x4064ac, 1, 0x04, 0x00003fff }, + { 0x4064b0, 3, 0x04, 0x00000000 }, + { 0x4064c0, 1, 0x04, 0x80400280 }, + { 0x4064c4, 1, 0x04, 0x0400ffff }, + { 0x4064c8, 1, 0x04, 0x018001ff }, + { 0x4064cc, 9, 0x04, 0x00000000 }, + { 0x4064fc, 1, 0x04, 0x0000022a }, + { 0x406500, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_be_0[] = { + { 0x408800, 1, 0x04, 0x32802a3c }, + { 0x408804, 1, 0x04, 0x00000040 }, + { 0x408808, 1, 0x04, 0x1003e005 }, + { 0x408840, 1, 0x04, 0x0000000b }, + { 0x408900, 1, 0x04, 0xb080b801 }, + { 0x408904, 1, 0x04, 0x63038001 }, + { 0x408908, 1, 0x04, 0x02c8102f }, + { 0x408980, 1, 0x04, 0x0000011d }, + {} +}; + +static const struct nvc0_graph_pack +gm107_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { gm107_grctx_init_fe_0 }, + { nvf0_grctx_init_pri_0 }, + { nve4_grctx_init_memfmt_0 }, + { gm107_grctx_init_ds_0 }, + { nvf0_grctx_init_cwd_0 }, + { gm107_grctx_init_pd_0 }, + { nv108_grctx_init_rstr2d_0 }, + { nve4_grctx_init_scc_0 }, + { gm107_grctx_init_be_0 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_gpc_unk_0[] = { + { 0x418380, 1, 0x04, 0x00000056 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_gpc_unk_1[] = { + { 0x418600, 1, 0x04, 0x0000007f }, + { 0x418684, 1, 0x04, 0x0000001f }, + { 0x418700, 1, 0x04, 0x00000002 }, + { 0x418704, 1, 0x04, 0x00000080 }, + { 0x418708, 1, 0x04, 0x40000000 }, + { 0x41870c, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_setup_0[] = { + { 0x418800, 1, 0x04, 0x7006863a }, + { 0x418810, 1, 0x04, 0x00000000 }, + { 0x418828, 1, 0x04, 0x00000044 }, + { 0x418830, 1, 0x04, 0x10000001 }, + { 0x4188d8, 1, 0x04, 0x00000008 }, + { 0x4188e0, 1, 0x04, 0x01000000 }, + { 0x4188e8, 5, 0x04, 0x00000000 }, + { 0x4188fc, 1, 0x04, 0x20100058 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_gpc_unk_2[] = { + { 0x418d24, 1, 0x04, 0x00000000 }, + { 0x418e00, 1, 0x04, 0x90000000 }, + { 0x418e24, 1, 0x04, 0x00000000 }, + { 0x418e28, 1, 0x04, 0x00000030 }, + { 0x418e30, 1, 0x04, 0x00000000 }, + { 0x418e34, 1, 0x04, 0x00010000 }, + { 0x418e38, 1, 0x04, 0x00000000 }, + { 0x418e40, 22, 0x04, 0x00000000 }, + { 0x418ea0, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +gm107_grctx_pack_gpc[] = { + { gm107_grctx_init_gpc_unk_0 }, + { nv108_grctx_init_prop_0 }, + { gm107_grctx_init_gpc_unk_1 }, + { gm107_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nv108_grctx_init_crstr_0 }, + { nve4_grctx_init_gpm_0 }, + { gm107_grctx_init_gpc_unk_2 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_tex_0[] = { + { 0x419a00, 1, 0x04, 0x000300f0 }, + { 0x419a04, 1, 0x04, 0x00000005 }, + { 0x419a08, 1, 0x04, 0x00000421 }, + { 0x419a0c, 1, 0x04, 0x00120000 }, + { 0x419a10, 1, 0x04, 0x00000000 }, + { 0x419a14, 1, 0x04, 0x00002200 }, + { 0x419a1c, 1, 0x04, 0x0000c000 }, + { 0x419a20, 1, 0x04, 0x20008a00 }, + { 0x419a30, 1, 0x04, 0x00000001 }, + { 0x419a3c, 1, 0x04, 0x00000002 }, + { 0x419ac4, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_mpc_0[] = { + { 0x419c00, 1, 0x04, 0x0000001a }, + { 0x419c04, 1, 0x04, 0x80000006 }, + { 0x419c08, 1, 0x04, 0x00000002 }, + { 0x419c20, 1, 0x04, 0x00000000 }, + { 0x419c24, 1, 0x04, 0x00084210 }, + { 0x419c28, 1, 0x04, 0x3efbefbe }, + { 0x419c2c, 1, 0x04, 0x00000000 }, + { 0x419c34, 1, 0x04, 0x01ff1ff3 }, + { 0x419c3c, 1, 0x04, 0x00001919 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_l1c_0[] = { + { 0x419c84, 1, 0x04, 0x00000020 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_sm_0[] = { + { 0x419e04, 3, 0x04, 0x00000000 }, + { 0x419e10, 1, 0x04, 0x00001c02 }, + { 0x419e44, 1, 0x04, 0x00d3eff2 }, + { 0x419e48, 1, 0x04, 0x00000000 }, + { 0x419e4c, 1, 0x04, 0x0000007f }, + { 0x419e50, 1, 0x04, 0x00000000 }, + { 0x419e60, 4, 0x04, 0x00000000 }, + { 0x419e74, 10, 0x04, 0x00000000 }, + { 0x419eac, 1, 0x04, 0x0001cf8b }, + { 0x419eb0, 1, 0x04, 0x00030300 }, + { 0x419eb8, 1, 0x04, 0x00000000 }, + { 0x419ef0, 24, 0x04, 0x00000000 }, + { 0x419f68, 2, 0x04, 0x00000000 }, + { 0x419f70, 1, 0x04, 0x00000020 }, + { 0x419f78, 1, 0x04, 0x000003eb }, + { 0x419f7c, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +gm107_grctx_pack_tpc[] = { + { nvd7_grctx_init_pe_0 }, + { gm107_grctx_init_tex_0 }, + { gm107_grctx_init_mpc_0 }, + { gm107_grctx_init_l1c_0 }, + { gm107_grctx_init_sm_0 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_cbm_0[] = { + { 0x41bec0, 1, 0x04, 0x00000000 }, + { 0x41bec4, 1, 0x04, 0x01050000 }, + { 0x41bee4, 1, 0x04, 0x00000000 }, + { 0x41bef0, 1, 0x04, 0x000003ff }, + { 0x41bef4, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_grctx_init_wwdx_0[] = { + { 0x41bf00, 1, 0x04, 0x0a418820 }, + { 0x41bf04, 1, 0x04, 0x062080e6 }, + { 0x41bf08, 1, 0x04, 0x020398a4 }, + { 0x41bf0c, 1, 0x04, 0x0e629062 }, + { 0x41bf10, 1, 0x04, 0x0a418820 }, + { 0x41bf14, 1, 0x04, 0x000000e6 }, + { 0x41bfd0, 1, 0x04, 0x00900103 }, + { 0x41bfe0, 1, 0x04, 0x80000000 }, + { 0x41bfe4, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +gm107_grctx_pack_ppc[] = { + { nve4_grctx_init_pes_0 }, + { gm107_grctx_init_cbm_0 }, + { gm107_grctx_init_wwdx_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + +static void +gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, 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); +} + +static void +gm107_grctx_generate_tpcid(struct nvc0_graph_priv *priv) +{ + int gpc, tpc, id; + + for (tpc = 0, id = 0; tpc < 4; tpc++) { + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + if (tpc < priv->tpc_nr[gpc]) { + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id); + nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id); + id++; + } + + nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]); + nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]); + } + } +} + +static void +gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) +{ + struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass; + int i; + + nvc0_graph_mmio(priv, oclass->hub); + nvc0_graph_mmio(priv, oclass->gpc); + nvc0_graph_mmio(priv, oclass->zcull); + nvc0_graph_mmio(priv, oclass->tpc); + nvc0_graph_mmio(priv, oclass->ppc); + + nv_wr32(priv, 0x404154, 0x00000000); + + oclass->mods(priv, info); + oclass->unkn(priv); + + gm107_grctx_generate_tpcid(priv); + nvc0_grctx_generate_r406028(priv); + nve4_grctx_generate_r418bb8(priv); + nvc0_grctx_generate_r406800(priv); + + nv_wr32(priv, 0x4064d0, 0x00000001); + for (i = 1; i < 8; i++) + nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000); + nv_wr32(priv, 0x406500, 0x00000001); + + nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr); + + if (priv->gpc_nr == 1) { + nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]); + nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]); + } else { + nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr); + nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr); + } + + nvc0_graph_icmd(priv, oclass->icmd); + nv_wr32(priv, 0x404154, 0x00000400); + nvc0_graph_mthd(priv, oclass->mthd); + + nv_mask(priv, 0x419e00, 0x00808080, 0x00808080); + nv_mask(priv, 0x419ccc, 0x80000000, 0x80000000); + nv_mask(priv, 0x419f80, 0x80000000, 0x80000000); + nv_mask(priv, 0x419f88, 0x80000000, 0x80000000); +} + +struct nouveau_oclass * +gm107_grctx_oclass = &(struct nvc0_grctx_oclass) { + .base.handle = NV_ENGCTX(GR, 0x08), + .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 = gm107_grctx_generate_main, + .mods = gm107_grctx_generate_mods, + .unkn = nve4_grctx_generate_unkn, + .hub = gm107_grctx_pack_hub, + .gpc = gm107_grctx_pack_gpc, + .zcull = nvc0_grctx_pack_zcull, + .tpc = gm107_grctx_pack_tpc, + .ppc = gm107_grctx_pack_ppc, + .icmd = gm107_grctx_pack_icmd, + .mthd = gm107_grctx_pack_mthd, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c index a86bd3352bf..8de4a429154 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c @@ -22,10 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -static struct nvc0_graph_init -nv108_grctx_init_icmd[] = { +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nv108_grctx_init_icmd_0[] = { { 0x001000, 1, 0x01, 0x00000004 }, { 0x000039, 3, 0x01, 0x00000000 }, { 0x0000a9, 1, 0x01, 0x0000ffff }, @@ -274,839 +278,14 @@ nv108_grctx_init_icmd[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_a197[] = { - { 0x000800, 1, 0x04, 0x00000000 }, - { 0x000840, 1, 0x04, 0x00000000 }, - { 0x000880, 1, 0x04, 0x00000000 }, - { 0x0008c0, 1, 0x04, 0x00000000 }, - { 0x000900, 1, 0x04, 0x00000000 }, - { 0x000940, 1, 0x04, 0x00000000 }, - { 0x000980, 1, 0x04, 0x00000000 }, - { 0x0009c0, 1, 0x04, 0x00000000 }, - { 0x000804, 1, 0x04, 0x00000000 }, - { 0x000844, 1, 0x04, 0x00000000 }, - { 0x000884, 1, 0x04, 0x00000000 }, - { 0x0008c4, 1, 0x04, 0x00000000 }, - { 0x000904, 1, 0x04, 0x00000000 }, - { 0x000944, 1, 0x04, 0x00000000 }, - { 0x000984, 1, 0x04, 0x00000000 }, - { 0x0009c4, 1, 0x04, 0x00000000 }, - { 0x000808, 1, 0x04, 0x00000400 }, - { 0x000848, 1, 0x04, 0x00000400 }, - { 0x000888, 1, 0x04, 0x00000400 }, - { 0x0008c8, 1, 0x04, 0x00000400 }, - { 0x000908, 1, 0x04, 0x00000400 }, - { 0x000948, 1, 0x04, 0x00000400 }, - { 0x000988, 1, 0x04, 0x00000400 }, - { 0x0009c8, 1, 0x04, 0x00000400 }, - { 0x00080c, 1, 0x04, 0x00000300 }, - { 0x00084c, 1, 0x04, 0x00000300 }, - { 0x00088c, 1, 0x04, 0x00000300 }, - { 0x0008cc, 1, 0x04, 0x00000300 }, - { 0x00090c, 1, 0x04, 0x00000300 }, - { 0x00094c, 1, 0x04, 0x00000300 }, - { 0x00098c, 1, 0x04, 0x00000300 }, - { 0x0009cc, 1, 0x04, 0x00000300 }, - { 0x000810, 1, 0x04, 0x000000cf }, - { 0x000850, 1, 0x04, 0x00000000 }, - { 0x000890, 1, 0x04, 0x00000000 }, - { 0x0008d0, 1, 0x04, 0x00000000 }, - { 0x000910, 1, 0x04, 0x00000000 }, - { 0x000950, 1, 0x04, 0x00000000 }, - { 0x000990, 1, 0x04, 0x00000000 }, - { 0x0009d0, 1, 0x04, 0x00000000 }, - { 0x000814, 1, 0x04, 0x00000040 }, - { 0x000854, 1, 0x04, 0x00000040 }, - { 0x000894, 1, 0x04, 0x00000040 }, - { 0x0008d4, 1, 0x04, 0x00000040 }, - { 0x000914, 1, 0x04, 0x00000040 }, - { 0x000954, 1, 0x04, 0x00000040 }, - { 0x000994, 1, 0x04, 0x00000040 }, - { 0x0009d4, 1, 0x04, 0x00000040 }, - { 0x000818, 1, 0x04, 0x00000001 }, - { 0x000858, 1, 0x04, 0x00000001 }, - { 0x000898, 1, 0x04, 0x00000001 }, - { 0x0008d8, 1, 0x04, 0x00000001 }, - { 0x000918, 1, 0x04, 0x00000001 }, - { 0x000958, 1, 0x04, 0x00000001 }, - { 0x000998, 1, 0x04, 0x00000001 }, - { 0x0009d8, 1, 0x04, 0x00000001 }, - { 0x00081c, 1, 0x04, 0x00000000 }, - { 0x00085c, 1, 0x04, 0x00000000 }, - { 0x00089c, 1, 0x04, 0x00000000 }, - { 0x0008dc, 1, 0x04, 0x00000000 }, - { 0x00091c, 1, 0x04, 0x00000000 }, - { 0x00095c, 1, 0x04, 0x00000000 }, - { 0x00099c, 1, 0x04, 0x00000000 }, - { 0x0009dc, 1, 0x04, 0x00000000 }, - { 0x000820, 1, 0x04, 0x00000000 }, - { 0x000860, 1, 0x04, 0x00000000 }, - { 0x0008a0, 1, 0x04, 0x00000000 }, - { 0x0008e0, 1, 0x04, 0x00000000 }, - { 0x000920, 1, 0x04, 0x00000000 }, - { 0x000960, 1, 0x04, 0x00000000 }, - { 0x0009a0, 1, 0x04, 0x00000000 }, - { 0x0009e0, 1, 0x04, 0x00000000 }, - { 0x001c00, 1, 0x04, 0x00000000 }, - { 0x001c10, 1, 0x04, 0x00000000 }, - { 0x001c20, 1, 0x04, 0x00000000 }, - { 0x001c30, 1, 0x04, 0x00000000 }, - { 0x001c40, 1, 0x04, 0x00000000 }, - { 0x001c50, 1, 0x04, 0x00000000 }, - { 0x001c60, 1, 0x04, 0x00000000 }, - { 0x001c70, 1, 0x04, 0x00000000 }, - { 0x001c80, 1, 0x04, 0x00000000 }, - { 0x001c90, 1, 0x04, 0x00000000 }, - { 0x001ca0, 1, 0x04, 0x00000000 }, - { 0x001cb0, 1, 0x04, 0x00000000 }, - { 0x001cc0, 1, 0x04, 0x00000000 }, - { 0x001cd0, 1, 0x04, 0x00000000 }, - { 0x001ce0, 1, 0x04, 0x00000000 }, - { 0x001cf0, 1, 0x04, 0x00000000 }, - { 0x001c04, 1, 0x04, 0x00000000 }, - { 0x001c14, 1, 0x04, 0x00000000 }, - { 0x001c24, 1, 0x04, 0x00000000 }, - { 0x001c34, 1, 0x04, 0x00000000 }, - { 0x001c44, 1, 0x04, 0x00000000 }, - { 0x001c54, 1, 0x04, 0x00000000 }, - { 0x001c64, 1, 0x04, 0x00000000 }, - { 0x001c74, 1, 0x04, 0x00000000 }, - { 0x001c84, 1, 0x04, 0x00000000 }, - { 0x001c94, 1, 0x04, 0x00000000 }, - { 0x001ca4, 1, 0x04, 0x00000000 }, - { 0x001cb4, 1, 0x04, 0x00000000 }, - { 0x001cc4, 1, 0x04, 0x00000000 }, - { 0x001cd4, 1, 0x04, 0x00000000 }, - { 0x001ce4, 1, 0x04, 0x00000000 }, - { 0x001cf4, 1, 0x04, 0x00000000 }, - { 0x001c08, 1, 0x04, 0x00000000 }, - { 0x001c18, 1, 0x04, 0x00000000 }, - { 0x001c28, 1, 0x04, 0x00000000 }, - { 0x001c38, 1, 0x04, 0x00000000 }, - { 0x001c48, 1, 0x04, 0x00000000 }, - { 0x001c58, 1, 0x04, 0x00000000 }, - { 0x001c68, 1, 0x04, 0x00000000 }, - { 0x001c78, 1, 0x04, 0x00000000 }, - { 0x001c88, 1, 0x04, 0x00000000 }, - { 0x001c98, 1, 0x04, 0x00000000 }, - { 0x001ca8, 1, 0x04, 0x00000000 }, - { 0x001cb8, 1, 0x04, 0x00000000 }, - { 0x001cc8, 1, 0x04, 0x00000000 }, - { 0x001cd8, 1, 0x04, 0x00000000 }, - { 0x001ce8, 1, 0x04, 0x00000000 }, - { 0x001cf8, 1, 0x04, 0x00000000 }, - { 0x001c0c, 1, 0x04, 0x00000000 }, - { 0x001c1c, 1, 0x04, 0x00000000 }, - { 0x001c2c, 1, 0x04, 0x00000000 }, - { 0x001c3c, 1, 0x04, 0x00000000 }, - { 0x001c4c, 1, 0x04, 0x00000000 }, - { 0x001c5c, 1, 0x04, 0x00000000 }, - { 0x001c6c, 1, 0x04, 0x00000000 }, - { 0x001c7c, 1, 0x04, 0x00000000 }, - { 0x001c8c, 1, 0x04, 0x00000000 }, - { 0x001c9c, 1, 0x04, 0x00000000 }, - { 0x001cac, 1, 0x04, 0x00000000 }, - { 0x001cbc, 1, 0x04, 0x00000000 }, - { 0x001ccc, 1, 0x04, 0x00000000 }, - { 0x001cdc, 1, 0x04, 0x00000000 }, - { 0x001cec, 1, 0x04, 0x00000000 }, - { 0x001cfc, 2, 0x04, 0x00000000 }, - { 0x001d10, 1, 0x04, 0x00000000 }, - { 0x001d20, 1, 0x04, 0x00000000 }, - { 0x001d30, 1, 0x04, 0x00000000 }, - { 0x001d40, 1, 0x04, 0x00000000 }, - { 0x001d50, 1, 0x04, 0x00000000 }, - { 0x001d60, 1, 0x04, 0x00000000 }, - { 0x001d70, 1, 0x04, 0x00000000 }, - { 0x001d80, 1, 0x04, 0x00000000 }, - { 0x001d90, 1, 0x04, 0x00000000 }, - { 0x001da0, 1, 0x04, 0x00000000 }, - { 0x001db0, 1, 0x04, 0x00000000 }, - { 0x001dc0, 1, 0x04, 0x00000000 }, - { 0x001dd0, 1, 0x04, 0x00000000 }, - { 0x001de0, 1, 0x04, 0x00000000 }, - { 0x001df0, 1, 0x04, 0x00000000 }, - { 0x001d04, 1, 0x04, 0x00000000 }, - { 0x001d14, 1, 0x04, 0x00000000 }, - { 0x001d24, 1, 0x04, 0x00000000 }, - { 0x001d34, 1, 0x04, 0x00000000 }, - { 0x001d44, 1, 0x04, 0x00000000 }, - { 0x001d54, 1, 0x04, 0x00000000 }, - { 0x001d64, 1, 0x04, 0x00000000 }, - { 0x001d74, 1, 0x04, 0x00000000 }, - { 0x001d84, 1, 0x04, 0x00000000 }, - { 0x001d94, 1, 0x04, 0x00000000 }, - { 0x001da4, 1, 0x04, 0x00000000 }, - { 0x001db4, 1, 0x04, 0x00000000 }, - { 0x001dc4, 1, 0x04, 0x00000000 }, - { 0x001dd4, 1, 0x04, 0x00000000 }, - { 0x001de4, 1, 0x04, 0x00000000 }, - { 0x001df4, 1, 0x04, 0x00000000 }, - { 0x001d08, 1, 0x04, 0x00000000 }, - { 0x001d18, 1, 0x04, 0x00000000 }, - { 0x001d28, 1, 0x04, 0x00000000 }, - { 0x001d38, 1, 0x04, 0x00000000 }, - { 0x001d48, 1, 0x04, 0x00000000 }, - { 0x001d58, 1, 0x04, 0x00000000 }, - { 0x001d68, 1, 0x04, 0x00000000 }, - { 0x001d78, 1, 0x04, 0x00000000 }, - { 0x001d88, 1, 0x04, 0x00000000 }, - { 0x001d98, 1, 0x04, 0x00000000 }, - { 0x001da8, 1, 0x04, 0x00000000 }, - { 0x001db8, 1, 0x04, 0x00000000 }, - { 0x001dc8, 1, 0x04, 0x00000000 }, - { 0x001dd8, 1, 0x04, 0x00000000 }, - { 0x001de8, 1, 0x04, 0x00000000 }, - { 0x001df8, 1, 0x04, 0x00000000 }, - { 0x001d0c, 1, 0x04, 0x00000000 }, - { 0x001d1c, 1, 0x04, 0x00000000 }, - { 0x001d2c, 1, 0x04, 0x00000000 }, - { 0x001d3c, 1, 0x04, 0x00000000 }, - { 0x001d4c, 1, 0x04, 0x00000000 }, - { 0x001d5c, 1, 0x04, 0x00000000 }, - { 0x001d6c, 1, 0x04, 0x00000000 }, - { 0x001d7c, 1, 0x04, 0x00000000 }, - { 0x001d8c, 1, 0x04, 0x00000000 }, - { 0x001d9c, 1, 0x04, 0x00000000 }, - { 0x001dac, 1, 0x04, 0x00000000 }, - { 0x001dbc, 1, 0x04, 0x00000000 }, - { 0x001dcc, 1, 0x04, 0x00000000 }, - { 0x001ddc, 1, 0x04, 0x00000000 }, - { 0x001dec, 1, 0x04, 0x00000000 }, - { 0x001dfc, 1, 0x04, 0x00000000 }, - { 0x001f00, 1, 0x04, 0x00000000 }, - { 0x001f08, 1, 0x04, 0x00000000 }, - { 0x001f10, 1, 0x04, 0x00000000 }, - { 0x001f18, 1, 0x04, 0x00000000 }, - { 0x001f20, 1, 0x04, 0x00000000 }, - { 0x001f28, 1, 0x04, 0x00000000 }, - { 0x001f30, 1, 0x04, 0x00000000 }, - { 0x001f38, 1, 0x04, 0x00000000 }, - { 0x001f40, 1, 0x04, 0x00000000 }, - { 0x001f48, 1, 0x04, 0x00000000 }, - { 0x001f50, 1, 0x04, 0x00000000 }, - { 0x001f58, 1, 0x04, 0x00000000 }, - { 0x001f60, 1, 0x04, 0x00000000 }, - { 0x001f68, 1, 0x04, 0x00000000 }, - { 0x001f70, 1, 0x04, 0x00000000 }, - { 0x001f78, 1, 0x04, 0x00000000 }, - { 0x001f04, 1, 0x04, 0x00000000 }, - { 0x001f0c, 1, 0x04, 0x00000000 }, - { 0x001f14, 1, 0x04, 0x00000000 }, - { 0x001f1c, 1, 0x04, 0x00000000 }, - { 0x001f24, 1, 0x04, 0x00000000 }, - { 0x001f2c, 1, 0x04, 0x00000000 }, - { 0x001f34, 1, 0x04, 0x00000000 }, - { 0x001f3c, 1, 0x04, 0x00000000 }, - { 0x001f44, 1, 0x04, 0x00000000 }, - { 0x001f4c, 1, 0x04, 0x00000000 }, - { 0x001f54, 1, 0x04, 0x00000000 }, - { 0x001f5c, 1, 0x04, 0x00000000 }, - { 0x001f64, 1, 0x04, 0x00000000 }, - { 0x001f6c, 1, 0x04, 0x00000000 }, - { 0x001f74, 1, 0x04, 0x00000000 }, - { 0x001f7c, 2, 0x04, 0x00000000 }, - { 0x001f88, 1, 0x04, 0x00000000 }, - { 0x001f90, 1, 0x04, 0x00000000 }, - { 0x001f98, 1, 0x04, 0x00000000 }, - { 0x001fa0, 1, 0x04, 0x00000000 }, - { 0x001fa8, 1, 0x04, 0x00000000 }, - { 0x001fb0, 1, 0x04, 0x00000000 }, - { 0x001fb8, 1, 0x04, 0x00000000 }, - { 0x001fc0, 1, 0x04, 0x00000000 }, - { 0x001fc8, 1, 0x04, 0x00000000 }, - { 0x001fd0, 1, 0x04, 0x00000000 }, - { 0x001fd8, 1, 0x04, 0x00000000 }, - { 0x001fe0, 1, 0x04, 0x00000000 }, - { 0x001fe8, 1, 0x04, 0x00000000 }, - { 0x001ff0, 1, 0x04, 0x00000000 }, - { 0x001ff8, 1, 0x04, 0x00000000 }, - { 0x001f84, 1, 0x04, 0x00000000 }, - { 0x001f8c, 1, 0x04, 0x00000000 }, - { 0x001f94, 1, 0x04, 0x00000000 }, - { 0x001f9c, 1, 0x04, 0x00000000 }, - { 0x001fa4, 1, 0x04, 0x00000000 }, - { 0x001fac, 1, 0x04, 0x00000000 }, - { 0x001fb4, 1, 0x04, 0x00000000 }, - { 0x001fbc, 1, 0x04, 0x00000000 }, - { 0x001fc4, 1, 0x04, 0x00000000 }, - { 0x001fcc, 1, 0x04, 0x00000000 }, - { 0x001fd4, 1, 0x04, 0x00000000 }, - { 0x001fdc, 1, 0x04, 0x00000000 }, - { 0x001fe4, 1, 0x04, 0x00000000 }, - { 0x001fec, 1, 0x04, 0x00000000 }, - { 0x001ff4, 1, 0x04, 0x00000000 }, - { 0x001ffc, 2, 0x04, 0x00000000 }, - { 0x002040, 1, 0x04, 0x00000011 }, - { 0x002080, 1, 0x04, 0x00000020 }, - { 0x0020c0, 1, 0x04, 0x00000030 }, - { 0x002100, 1, 0x04, 0x00000040 }, - { 0x002140, 1, 0x04, 0x00000051 }, - { 0x00200c, 1, 0x04, 0x00000001 }, - { 0x00204c, 1, 0x04, 0x00000001 }, - { 0x00208c, 1, 0x04, 0x00000001 }, - { 0x0020cc, 1, 0x04, 0x00000001 }, - { 0x00210c, 1, 0x04, 0x00000001 }, - { 0x00214c, 1, 0x04, 0x00000001 }, - { 0x002010, 1, 0x04, 0x00000000 }, - { 0x002050, 1, 0x04, 0x00000000 }, - { 0x002090, 1, 0x04, 0x00000001 }, - { 0x0020d0, 1, 0x04, 0x00000002 }, - { 0x002110, 1, 0x04, 0x00000003 }, - { 0x002150, 1, 0x04, 0x00000004 }, - { 0x000380, 1, 0x04, 0x00000000 }, - { 0x0003a0, 1, 0x04, 0x00000000 }, - { 0x0003c0, 1, 0x04, 0x00000000 }, - { 0x0003e0, 1, 0x04, 0x00000000 }, - { 0x000384, 1, 0x04, 0x00000000 }, - { 0x0003a4, 1, 0x04, 0x00000000 }, - { 0x0003c4, 1, 0x04, 0x00000000 }, - { 0x0003e4, 1, 0x04, 0x00000000 }, - { 0x000388, 1, 0x04, 0x00000000 }, - { 0x0003a8, 1, 0x04, 0x00000000 }, - { 0x0003c8, 1, 0x04, 0x00000000 }, - { 0x0003e8, 1, 0x04, 0x00000000 }, - { 0x00038c, 1, 0x04, 0x00000000 }, - { 0x0003ac, 1, 0x04, 0x00000000 }, - { 0x0003cc, 1, 0x04, 0x00000000 }, - { 0x0003ec, 1, 0x04, 0x00000000 }, - { 0x000700, 1, 0x04, 0x00000000 }, - { 0x000710, 1, 0x04, 0x00000000 }, - { 0x000720, 1, 0x04, 0x00000000 }, - { 0x000730, 1, 0x04, 0x00000000 }, - { 0x000704, 1, 0x04, 0x00000000 }, - { 0x000714, 1, 0x04, 0x00000000 }, - { 0x000724, 1, 0x04, 0x00000000 }, - { 0x000734, 1, 0x04, 0x00000000 }, - { 0x000708, 1, 0x04, 0x00000000 }, - { 0x000718, 1, 0x04, 0x00000000 }, - { 0x000728, 1, 0x04, 0x00000000 }, - { 0x000738, 1, 0x04, 0x00000000 }, - { 0x002800, 128, 0x04, 0x00000000 }, - { 0x000a00, 1, 0x04, 0x00000000 }, - { 0x000a20, 1, 0x04, 0x00000000 }, - { 0x000a40, 1, 0x04, 0x00000000 }, - { 0x000a60, 1, 0x04, 0x00000000 }, - { 0x000a80, 1, 0x04, 0x00000000 }, - { 0x000aa0, 1, 0x04, 0x00000000 }, - { 0x000ac0, 1, 0x04, 0x00000000 }, - { 0x000ae0, 1, 0x04, 0x00000000 }, - { 0x000b00, 1, 0x04, 0x00000000 }, - { 0x000b20, 1, 0x04, 0x00000000 }, - { 0x000b40, 1, 0x04, 0x00000000 }, - { 0x000b60, 1, 0x04, 0x00000000 }, - { 0x000b80, 1, 0x04, 0x00000000 }, - { 0x000ba0, 1, 0x04, 0x00000000 }, - { 0x000bc0, 1, 0x04, 0x00000000 }, - { 0x000be0, 1, 0x04, 0x00000000 }, - { 0x000a04, 1, 0x04, 0x00000000 }, - { 0x000a24, 1, 0x04, 0x00000000 }, - { 0x000a44, 1, 0x04, 0x00000000 }, - { 0x000a64, 1, 0x04, 0x00000000 }, - { 0x000a84, 1, 0x04, 0x00000000 }, - { 0x000aa4, 1, 0x04, 0x00000000 }, - { 0x000ac4, 1, 0x04, 0x00000000 }, - { 0x000ae4, 1, 0x04, 0x00000000 }, - { 0x000b04, 1, 0x04, 0x00000000 }, - { 0x000b24, 1, 0x04, 0x00000000 }, - { 0x000b44, 1, 0x04, 0x00000000 }, - { 0x000b64, 1, 0x04, 0x00000000 }, - { 0x000b84, 1, 0x04, 0x00000000 }, - { 0x000ba4, 1, 0x04, 0x00000000 }, - { 0x000bc4, 1, 0x04, 0x00000000 }, - { 0x000be4, 1, 0x04, 0x00000000 }, - { 0x000a08, 1, 0x04, 0x00000000 }, - { 0x000a28, 1, 0x04, 0x00000000 }, - { 0x000a48, 1, 0x04, 0x00000000 }, - { 0x000a68, 1, 0x04, 0x00000000 }, - { 0x000a88, 1, 0x04, 0x00000000 }, - { 0x000aa8, 1, 0x04, 0x00000000 }, - { 0x000ac8, 1, 0x04, 0x00000000 }, - { 0x000ae8, 1, 0x04, 0x00000000 }, - { 0x000b08, 1, 0x04, 0x00000000 }, - { 0x000b28, 1, 0x04, 0x00000000 }, - { 0x000b48, 1, 0x04, 0x00000000 }, - { 0x000b68, 1, 0x04, 0x00000000 }, - { 0x000b88, 1, 0x04, 0x00000000 }, - { 0x000ba8, 1, 0x04, 0x00000000 }, - { 0x000bc8, 1, 0x04, 0x00000000 }, - { 0x000be8, 1, 0x04, 0x00000000 }, - { 0x000a0c, 1, 0x04, 0x00000000 }, - { 0x000a2c, 1, 0x04, 0x00000000 }, - { 0x000a4c, 1, 0x04, 0x00000000 }, - { 0x000a6c, 1, 0x04, 0x00000000 }, - { 0x000a8c, 1, 0x04, 0x00000000 }, - { 0x000aac, 1, 0x04, 0x00000000 }, - { 0x000acc, 1, 0x04, 0x00000000 }, - { 0x000aec, 1, 0x04, 0x00000000 }, - { 0x000b0c, 1, 0x04, 0x00000000 }, - { 0x000b2c, 1, 0x04, 0x00000000 }, - { 0x000b4c, 1, 0x04, 0x00000000 }, - { 0x000b6c, 1, 0x04, 0x00000000 }, - { 0x000b8c, 1, 0x04, 0x00000000 }, - { 0x000bac, 1, 0x04, 0x00000000 }, - { 0x000bcc, 1, 0x04, 0x00000000 }, - { 0x000bec, 1, 0x04, 0x00000000 }, - { 0x000a10, 1, 0x04, 0x00000000 }, - { 0x000a30, 1, 0x04, 0x00000000 }, - { 0x000a50, 1, 0x04, 0x00000000 }, - { 0x000a70, 1, 0x04, 0x00000000 }, - { 0x000a90, 1, 0x04, 0x00000000 }, - { 0x000ab0, 1, 0x04, 0x00000000 }, - { 0x000ad0, 1, 0x04, 0x00000000 }, - { 0x000af0, 1, 0x04, 0x00000000 }, - { 0x000b10, 1, 0x04, 0x00000000 }, - { 0x000b30, 1, 0x04, 0x00000000 }, - { 0x000b50, 1, 0x04, 0x00000000 }, - { 0x000b70, 1, 0x04, 0x00000000 }, - { 0x000b90, 1, 0x04, 0x00000000 }, - { 0x000bb0, 1, 0x04, 0x00000000 }, - { 0x000bd0, 1, 0x04, 0x00000000 }, - { 0x000bf0, 1, 0x04, 0x00000000 }, - { 0x000a14, 1, 0x04, 0x00000000 }, - { 0x000a34, 1, 0x04, 0x00000000 }, - { 0x000a54, 1, 0x04, 0x00000000 }, - { 0x000a74, 1, 0x04, 0x00000000 }, - { 0x000a94, 1, 0x04, 0x00000000 }, - { 0x000ab4, 1, 0x04, 0x00000000 }, - { 0x000ad4, 1, 0x04, 0x00000000 }, - { 0x000af4, 1, 0x04, 0x00000000 }, - { 0x000b14, 1, 0x04, 0x00000000 }, - { 0x000b34, 1, 0x04, 0x00000000 }, - { 0x000b54, 1, 0x04, 0x00000000 }, - { 0x000b74, 1, 0x04, 0x00000000 }, - { 0x000b94, 1, 0x04, 0x00000000 }, - { 0x000bb4, 1, 0x04, 0x00000000 }, - { 0x000bd4, 1, 0x04, 0x00000000 }, - { 0x000bf4, 1, 0x04, 0x00000000 }, - { 0x000c00, 1, 0x04, 0x00000000 }, - { 0x000c10, 1, 0x04, 0x00000000 }, - { 0x000c20, 1, 0x04, 0x00000000 }, - { 0x000c30, 1, 0x04, 0x00000000 }, - { 0x000c40, 1, 0x04, 0x00000000 }, - { 0x000c50, 1, 0x04, 0x00000000 }, - { 0x000c60, 1, 0x04, 0x00000000 }, - { 0x000c70, 1, 0x04, 0x00000000 }, - { 0x000c80, 1, 0x04, 0x00000000 }, - { 0x000c90, 1, 0x04, 0x00000000 }, - { 0x000ca0, 1, 0x04, 0x00000000 }, - { 0x000cb0, 1, 0x04, 0x00000000 }, - { 0x000cc0, 1, 0x04, 0x00000000 }, - { 0x000cd0, 1, 0x04, 0x00000000 }, - { 0x000ce0, 1, 0x04, 0x00000000 }, - { 0x000cf0, 1, 0x04, 0x00000000 }, - { 0x000c04, 1, 0x04, 0x00000000 }, - { 0x000c14, 1, 0x04, 0x00000000 }, - { 0x000c24, 1, 0x04, 0x00000000 }, - { 0x000c34, 1, 0x04, 0x00000000 }, - { 0x000c44, 1, 0x04, 0x00000000 }, - { 0x000c54, 1, 0x04, 0x00000000 }, - { 0x000c64, 1, 0x04, 0x00000000 }, - { 0x000c74, 1, 0x04, 0x00000000 }, - { 0x000c84, 1, 0x04, 0x00000000 }, - { 0x000c94, 1, 0x04, 0x00000000 }, - { 0x000ca4, 1, 0x04, 0x00000000 }, - { 0x000cb4, 1, 0x04, 0x00000000 }, - { 0x000cc4, 1, 0x04, 0x00000000 }, - { 0x000cd4, 1, 0x04, 0x00000000 }, - { 0x000ce4, 1, 0x04, 0x00000000 }, - { 0x000cf4, 1, 0x04, 0x00000000 }, - { 0x000c08, 1, 0x04, 0x00000000 }, - { 0x000c18, 1, 0x04, 0x00000000 }, - { 0x000c28, 1, 0x04, 0x00000000 }, - { 0x000c38, 1, 0x04, 0x00000000 }, - { 0x000c48, 1, 0x04, 0x00000000 }, - { 0x000c58, 1, 0x04, 0x00000000 }, - { 0x000c68, 1, 0x04, 0x00000000 }, - { 0x000c78, 1, 0x04, 0x00000000 }, - { 0x000c88, 1, 0x04, 0x00000000 }, - { 0x000c98, 1, 0x04, 0x00000000 }, - { 0x000ca8, 1, 0x04, 0x00000000 }, - { 0x000cb8, 1, 0x04, 0x00000000 }, - { 0x000cc8, 1, 0x04, 0x00000000 }, - { 0x000cd8, 1, 0x04, 0x00000000 }, - { 0x000ce8, 1, 0x04, 0x00000000 }, - { 0x000cf8, 1, 0x04, 0x00000000 }, - { 0x000c0c, 1, 0x04, 0x3f800000 }, - { 0x000c1c, 1, 0x04, 0x3f800000 }, - { 0x000c2c, 1, 0x04, 0x3f800000 }, - { 0x000c3c, 1, 0x04, 0x3f800000 }, - { 0x000c4c, 1, 0x04, 0x3f800000 }, - { 0x000c5c, 1, 0x04, 0x3f800000 }, - { 0x000c6c, 1, 0x04, 0x3f800000 }, - { 0x000c7c, 1, 0x04, 0x3f800000 }, - { 0x000c8c, 1, 0x04, 0x3f800000 }, - { 0x000c9c, 1, 0x04, 0x3f800000 }, - { 0x000cac, 1, 0x04, 0x3f800000 }, - { 0x000cbc, 1, 0x04, 0x3f800000 }, - { 0x000ccc, 1, 0x04, 0x3f800000 }, - { 0x000cdc, 1, 0x04, 0x3f800000 }, - { 0x000cec, 1, 0x04, 0x3f800000 }, - { 0x000cfc, 1, 0x04, 0x3f800000 }, - { 0x000d00, 1, 0x04, 0xffff0000 }, - { 0x000d08, 1, 0x04, 0xffff0000 }, - { 0x000d10, 1, 0x04, 0xffff0000 }, - { 0x000d18, 1, 0x04, 0xffff0000 }, - { 0x000d20, 1, 0x04, 0xffff0000 }, - { 0x000d28, 1, 0x04, 0xffff0000 }, - { 0x000d30, 1, 0x04, 0xffff0000 }, - { 0x000d38, 1, 0x04, 0xffff0000 }, - { 0x000d04, 1, 0x04, 0xffff0000 }, - { 0x000d0c, 1, 0x04, 0xffff0000 }, - { 0x000d14, 1, 0x04, 0xffff0000 }, - { 0x000d1c, 1, 0x04, 0xffff0000 }, - { 0x000d24, 1, 0x04, 0xffff0000 }, - { 0x000d2c, 1, 0x04, 0xffff0000 }, - { 0x000d34, 1, 0x04, 0xffff0000 }, - { 0x000d3c, 1, 0x04, 0xffff0000 }, - { 0x000e00, 1, 0x04, 0x00000000 }, - { 0x000e10, 1, 0x04, 0x00000000 }, - { 0x000e20, 1, 0x04, 0x00000000 }, - { 0x000e30, 1, 0x04, 0x00000000 }, - { 0x000e40, 1, 0x04, 0x00000000 }, - { 0x000e50, 1, 0x04, 0x00000000 }, - { 0x000e60, 1, 0x04, 0x00000000 }, - { 0x000e70, 1, 0x04, 0x00000000 }, - { 0x000e80, 1, 0x04, 0x00000000 }, - { 0x000e90, 1, 0x04, 0x00000000 }, - { 0x000ea0, 1, 0x04, 0x00000000 }, - { 0x000eb0, 1, 0x04, 0x00000000 }, - { 0x000ec0, 1, 0x04, 0x00000000 }, - { 0x000ed0, 1, 0x04, 0x00000000 }, - { 0x000ee0, 1, 0x04, 0x00000000 }, - { 0x000ef0, 1, 0x04, 0x00000000 }, - { 0x000e04, 1, 0x04, 0xffff0000 }, - { 0x000e14, 1, 0x04, 0xffff0000 }, - { 0x000e24, 1, 0x04, 0xffff0000 }, - { 0x000e34, 1, 0x04, 0xffff0000 }, - { 0x000e44, 1, 0x04, 0xffff0000 }, - { 0x000e54, 1, 0x04, 0xffff0000 }, - { 0x000e64, 1, 0x04, 0xffff0000 }, - { 0x000e74, 1, 0x04, 0xffff0000 }, - { 0x000e84, 1, 0x04, 0xffff0000 }, - { 0x000e94, 1, 0x04, 0xffff0000 }, - { 0x000ea4, 1, 0x04, 0xffff0000 }, - { 0x000eb4, 1, 0x04, 0xffff0000 }, - { 0x000ec4, 1, 0x04, 0xffff0000 }, - { 0x000ed4, 1, 0x04, 0xffff0000 }, - { 0x000ee4, 1, 0x04, 0xffff0000 }, - { 0x000ef4, 1, 0x04, 0xffff0000 }, - { 0x000e08, 1, 0x04, 0xffff0000 }, - { 0x000e18, 1, 0x04, 0xffff0000 }, - { 0x000e28, 1, 0x04, 0xffff0000 }, - { 0x000e38, 1, 0x04, 0xffff0000 }, - { 0x000e48, 1, 0x04, 0xffff0000 }, - { 0x000e58, 1, 0x04, 0xffff0000 }, - { 0x000e68, 1, 0x04, 0xffff0000 }, - { 0x000e78, 1, 0x04, 0xffff0000 }, - { 0x000e88, 1, 0x04, 0xffff0000 }, - { 0x000e98, 1, 0x04, 0xffff0000 }, - { 0x000ea8, 1, 0x04, 0xffff0000 }, - { 0x000eb8, 1, 0x04, 0xffff0000 }, - { 0x000ec8, 1, 0x04, 0xffff0000 }, - { 0x000ed8, 1, 0x04, 0xffff0000 }, - { 0x000ee8, 1, 0x04, 0xffff0000 }, - { 0x000ef8, 1, 0x04, 0xffff0000 }, - { 0x000d40, 1, 0x04, 0x00000000 }, - { 0x000d48, 1, 0x04, 0x00000000 }, - { 0x000d50, 1, 0x04, 0x00000000 }, - { 0x000d58, 1, 0x04, 0x00000000 }, - { 0x000d44, 1, 0x04, 0x00000000 }, - { 0x000d4c, 1, 0x04, 0x00000000 }, - { 0x000d54, 1, 0x04, 0x00000000 }, - { 0x000d5c, 1, 0x04, 0x00000000 }, - { 0x001e00, 1, 0x04, 0x00000001 }, - { 0x001e20, 1, 0x04, 0x00000001 }, - { 0x001e40, 1, 0x04, 0x00000001 }, - { 0x001e60, 1, 0x04, 0x00000001 }, - { 0x001e80, 1, 0x04, 0x00000001 }, - { 0x001ea0, 1, 0x04, 0x00000001 }, - { 0x001ec0, 1, 0x04, 0x00000001 }, - { 0x001ee0, 1, 0x04, 0x00000001 }, - { 0x001e04, 1, 0x04, 0x00000001 }, - { 0x001e24, 1, 0x04, 0x00000001 }, - { 0x001e44, 1, 0x04, 0x00000001 }, - { 0x001e64, 1, 0x04, 0x00000001 }, - { 0x001e84, 1, 0x04, 0x00000001 }, - { 0x001ea4, 1, 0x04, 0x00000001 }, - { 0x001ec4, 1, 0x04, 0x00000001 }, - { 0x001ee4, 1, 0x04, 0x00000001 }, - { 0x001e08, 1, 0x04, 0x00000002 }, - { 0x001e28, 1, 0x04, 0x00000002 }, - { 0x001e48, 1, 0x04, 0x00000002 }, - { 0x001e68, 1, 0x04, 0x00000002 }, - { 0x001e88, 1, 0x04, 0x00000002 }, - { 0x001ea8, 1, 0x04, 0x00000002 }, - { 0x001ec8, 1, 0x04, 0x00000002 }, - { 0x001ee8, 1, 0x04, 0x00000002 }, - { 0x001e0c, 1, 0x04, 0x00000001 }, - { 0x001e2c, 1, 0x04, 0x00000001 }, - { 0x001e4c, 1, 0x04, 0x00000001 }, - { 0x001e6c, 1, 0x04, 0x00000001 }, - { 0x001e8c, 1, 0x04, 0x00000001 }, - { 0x001eac, 1, 0x04, 0x00000001 }, - { 0x001ecc, 1, 0x04, 0x00000001 }, - { 0x001eec, 1, 0x04, 0x00000001 }, - { 0x001e10, 1, 0x04, 0x00000001 }, - { 0x001e30, 1, 0x04, 0x00000001 }, - { 0x001e50, 1, 0x04, 0x00000001 }, - { 0x001e70, 1, 0x04, 0x00000001 }, - { 0x001e90, 1, 0x04, 0x00000001 }, - { 0x001eb0, 1, 0x04, 0x00000001 }, - { 0x001ed0, 1, 0x04, 0x00000001 }, - { 0x001ef0, 1, 0x04, 0x00000001 }, - { 0x001e14, 1, 0x04, 0x00000002 }, - { 0x001e34, 1, 0x04, 0x00000002 }, - { 0x001e54, 1, 0x04, 0x00000002 }, - { 0x001e74, 1, 0x04, 0x00000002 }, - { 0x001e94, 1, 0x04, 0x00000002 }, - { 0x001eb4, 1, 0x04, 0x00000002 }, - { 0x001ed4, 1, 0x04, 0x00000002 }, - { 0x001ef4, 1, 0x04, 0x00000002 }, - { 0x001e18, 1, 0x04, 0x00000001 }, - { 0x001e38, 1, 0x04, 0x00000001 }, - { 0x001e58, 1, 0x04, 0x00000001 }, - { 0x001e78, 1, 0x04, 0x00000001 }, - { 0x001e98, 1, 0x04, 0x00000001 }, - { 0x001eb8, 1, 0x04, 0x00000001 }, - { 0x001ed8, 1, 0x04, 0x00000001 }, - { 0x001ef8, 1, 0x04, 0x00000001 }, - { 0x003400, 128, 0x04, 0x00000000 }, - { 0x00030c, 1, 0x04, 0x00000001 }, - { 0x001944, 1, 0x04, 0x00000000 }, - { 0x001514, 1, 0x04, 0x00000000 }, - { 0x000d68, 1, 0x04, 0x0000ffff }, - { 0x00121c, 1, 0x04, 0x0fac6881 }, - { 0x000fac, 1, 0x04, 0x00000001 }, - { 0x001538, 1, 0x04, 0x00000001 }, - { 0x000fe0, 2, 0x04, 0x00000000 }, - { 0x000fe8, 1, 0x04, 0x00000014 }, - { 0x000fec, 1, 0x04, 0x00000040 }, - { 0x000ff0, 1, 0x04, 0x00000000 }, - { 0x00179c, 1, 0x04, 0x00000000 }, - { 0x001228, 1, 0x04, 0x00000400 }, - { 0x00122c, 1, 0x04, 0x00000300 }, - { 0x001230, 1, 0x04, 0x00010001 }, - { 0x0007f8, 1, 0x04, 0x00000000 }, - { 0x0015b4, 1, 0x04, 0x00000001 }, - { 0x0015cc, 1, 0x04, 0x00000000 }, - { 0x001534, 1, 0x04, 0x00000000 }, - { 0x000fb0, 1, 0x04, 0x00000000 }, - { 0x0015d0, 1, 0x04, 0x00000000 }, - { 0x00153c, 1, 0x04, 0x00000000 }, - { 0x0016b4, 1, 0x04, 0x00000003 }, - { 0x000fbc, 4, 0x04, 0x0000ffff }, - { 0x000df8, 2, 0x04, 0x00000000 }, - { 0x001948, 1, 0x04, 0x00000000 }, - { 0x001970, 1, 0x04, 0x00000001 }, - { 0x00161c, 1, 0x04, 0x000009f0 }, - { 0x000dcc, 1, 0x04, 0x00000010 }, - { 0x00163c, 1, 0x04, 0x00000000 }, - { 0x0015e4, 1, 0x04, 0x00000000 }, - { 0x001160, 32, 0x04, 0x25e00040 }, - { 0x001880, 32, 0x04, 0x00000000 }, - { 0x000f84, 2, 0x04, 0x00000000 }, - { 0x0017c8, 2, 0x04, 0x00000000 }, - { 0x0017d0, 1, 0x04, 0x000000ff }, - { 0x0017d4, 1, 0x04, 0xffffffff }, - { 0x0017d8, 1, 0x04, 0x00000002 }, - { 0x0017dc, 1, 0x04, 0x00000000 }, - { 0x0015f4, 2, 0x04, 0x00000000 }, - { 0x001434, 2, 0x04, 0x00000000 }, - { 0x000d74, 1, 0x04, 0x00000000 }, - { 0x000dec, 1, 0x04, 0x00000001 }, - { 0x0013a4, 1, 0x04, 0x00000000 }, - { 0x001318, 1, 0x04, 0x00000001 }, - { 0x001644, 1, 0x04, 0x00000000 }, - { 0x000748, 1, 0x04, 0x00000000 }, - { 0x000de8, 1, 0x04, 0x00000000 }, - { 0x001648, 1, 0x04, 0x00000000 }, - { 0x0012a4, 1, 0x04, 0x00000000 }, - { 0x001120, 4, 0x04, 0x00000000 }, - { 0x001118, 1, 0x04, 0x00000000 }, - { 0x00164c, 1, 0x04, 0x00000000 }, - { 0x001658, 1, 0x04, 0x00000000 }, - { 0x001910, 1, 0x04, 0x00000290 }, - { 0x001518, 1, 0x04, 0x00000000 }, - { 0x00165c, 1, 0x04, 0x00000001 }, - { 0x001520, 1, 0x04, 0x00000000 }, - { 0x001604, 1, 0x04, 0x00000000 }, - { 0x001570, 1, 0x04, 0x00000000 }, - { 0x0013b0, 2, 0x04, 0x3f800000 }, - { 0x00020c, 1, 0x04, 0x00000000 }, - { 0x001670, 1, 0x04, 0x30201000 }, - { 0x001674, 1, 0x04, 0x70605040 }, - { 0x001678, 1, 0x04, 0xb8a89888 }, - { 0x00167c, 1, 0x04, 0xf8e8d8c8 }, - { 0x00166c, 1, 0x04, 0x00000000 }, - { 0x001680, 1, 0x04, 0x00ffff00 }, - { 0x0012d0, 1, 0x04, 0x00000003 }, - { 0x0012d4, 1, 0x04, 0x00000002 }, - { 0x001684, 2, 0x04, 0x00000000 }, - { 0x000dac, 2, 0x04, 0x00001b02 }, - { 0x000db4, 1, 0x04, 0x00000000 }, - { 0x00168c, 1, 0x04, 0x00000000 }, - { 0x0015bc, 1, 0x04, 0x00000000 }, - { 0x00156c, 1, 0x04, 0x00000000 }, - { 0x00187c, 1, 0x04, 0x00000000 }, - { 0x001110, 1, 0x04, 0x00000001 }, - { 0x000dc0, 3, 0x04, 0x00000000 }, - { 0x001234, 1, 0x04, 0x00000000 }, - { 0x001690, 1, 0x04, 0x00000000 }, - { 0x0012ac, 1, 0x04, 0x00000001 }, - { 0x0002c4, 1, 0x04, 0x00000000 }, - { 0x000790, 5, 0x04, 0x00000000 }, - { 0x00077c, 1, 0x04, 0x00000000 }, - { 0x001000, 1, 0x04, 0x00000010 }, - { 0x0010fc, 1, 0x04, 0x00000000 }, - { 0x001290, 1, 0x04, 0x00000000 }, - { 0x000218, 1, 0x04, 0x00000010 }, - { 0x0012d8, 1, 0x04, 0x00000000 }, - { 0x0012dc, 1, 0x04, 0x00000010 }, - { 0x000d94, 1, 0x04, 0x00000001 }, - { 0x00155c, 2, 0x04, 0x00000000 }, - { 0x001564, 1, 0x04, 0x00000fff }, - { 0x001574, 2, 0x04, 0x00000000 }, - { 0x00157c, 1, 0x04, 0x000fffff }, - { 0x001354, 1, 0x04, 0x00000000 }, - { 0x001610, 1, 0x04, 0x00000012 }, - { 0x001608, 2, 0x04, 0x00000000 }, - { 0x00260c, 1, 0x04, 0x00000000 }, - { 0x0007ac, 1, 0x04, 0x00000000 }, - { 0x00162c, 1, 0x04, 0x00000003 }, - { 0x000210, 1, 0x04, 0x00000000 }, - { 0x000320, 1, 0x04, 0x00000000 }, - { 0x000324, 6, 0x04, 0x3f800000 }, - { 0x000750, 1, 0x04, 0x00000000 }, - { 0x000760, 1, 0x04, 0x39291909 }, - { 0x000764, 1, 0x04, 0x79695949 }, - { 0x000768, 1, 0x04, 0xb9a99989 }, - { 0x00076c, 1, 0x04, 0xf9e9d9c9 }, - { 0x000770, 1, 0x04, 0x30201000 }, - { 0x000774, 1, 0x04, 0x70605040 }, - { 0x000778, 1, 0x04, 0x00009080 }, - { 0x000780, 1, 0x04, 0x39291909 }, - { 0x000784, 1, 0x04, 0x79695949 }, - { 0x000788, 1, 0x04, 0xb9a99989 }, - { 0x00078c, 1, 0x04, 0xf9e9d9c9 }, - { 0x0007d0, 1, 0x04, 0x30201000 }, - { 0x0007d4, 1, 0x04, 0x70605040 }, - { 0x0007d8, 1, 0x04, 0x00009080 }, - { 0x00037c, 1, 0x04, 0x00000001 }, - { 0x000740, 2, 0x04, 0x00000000 }, - { 0x002600, 1, 0x04, 0x00000000 }, - { 0x001918, 1, 0x04, 0x00000000 }, - { 0x00191c, 1, 0x04, 0x00000900 }, - { 0x001920, 1, 0x04, 0x00000405 }, - { 0x001308, 1, 0x04, 0x00000001 }, - { 0x001924, 1, 0x04, 0x00000000 }, - { 0x0013ac, 1, 0x04, 0x00000000 }, - { 0x00192c, 1, 0x04, 0x00000001 }, - { 0x00193c, 1, 0x04, 0x00002c1c }, - { 0x000d7c, 1, 0x04, 0x00000000 }, - { 0x000f8c, 1, 0x04, 0x00000000 }, - { 0x0002c0, 1, 0x04, 0x00000001 }, - { 0x001510, 1, 0x04, 0x00000000 }, - { 0x001940, 1, 0x04, 0x00000000 }, - { 0x000ff4, 2, 0x04, 0x00000000 }, - { 0x00194c, 2, 0x04, 0x00000000 }, - { 0x001968, 1, 0x04, 0x00000000 }, - { 0x001590, 1, 0x04, 0x0000003f }, - { 0x0007e8, 4, 0x04, 0x00000000 }, - { 0x00196c, 1, 0x04, 0x00000011 }, - { 0x0002e4, 1, 0x04, 0x0000b001 }, - { 0x00036c, 2, 0x04, 0x00000000 }, - { 0x00197c, 1, 0x04, 0x00000000 }, - { 0x000fcc, 2, 0x04, 0x00000000 }, - { 0x0002d8, 1, 0x04, 0x00000040 }, - { 0x001980, 1, 0x04, 0x00000080 }, - { 0x001504, 1, 0x04, 0x00000080 }, - { 0x001984, 1, 0x04, 0x00000000 }, - { 0x000300, 1, 0x04, 0x00000001 }, - { 0x0013a8, 1, 0x04, 0x00000000 }, - { 0x0012ec, 1, 0x04, 0x00000000 }, - { 0x001310, 1, 0x04, 0x00000000 }, - { 0x001314, 1, 0x04, 0x00000001 }, - { 0x001380, 1, 0x04, 0x00000000 }, - { 0x001384, 4, 0x04, 0x00000001 }, - { 0x001394, 1, 0x04, 0x00000000 }, - { 0x00139c, 1, 0x04, 0x00000000 }, - { 0x001398, 1, 0x04, 0x00000000 }, - { 0x001594, 1, 0x04, 0x00000000 }, - { 0x001598, 4, 0x04, 0x00000001 }, - { 0x000f54, 3, 0x04, 0x00000000 }, - { 0x0019bc, 1, 0x04, 0x00000000 }, - { 0x000f9c, 2, 0x04, 0x00000000 }, - { 0x0012cc, 1, 0x04, 0x00000000 }, - { 0x0012e8, 1, 0x04, 0x00000000 }, - { 0x00130c, 1, 0x04, 0x00000001 }, - { 0x001360, 8, 0x04, 0x00000000 }, - { 0x00133c, 2, 0x04, 0x00000001 }, - { 0x001344, 1, 0x04, 0x00000002 }, - { 0x001348, 2, 0x04, 0x00000001 }, - { 0x001350, 1, 0x04, 0x00000002 }, - { 0x001358, 1, 0x04, 0x00000001 }, - { 0x0012e4, 1, 0x04, 0x00000000 }, - { 0x00131c, 4, 0x04, 0x00000000 }, - { 0x0019c0, 1, 0x04, 0x00000000 }, - { 0x001140, 1, 0x04, 0x00000000 }, - { 0x0019c4, 1, 0x04, 0x00000000 }, - { 0x0019c8, 1, 0x04, 0x00001500 }, - { 0x00135c, 1, 0x04, 0x00000000 }, - { 0x000f90, 1, 0x04, 0x00000000 }, - { 0x0019e0, 8, 0x04, 0x00000001 }, - { 0x0019cc, 1, 0x04, 0x00000001 }, - { 0x0015b8, 1, 0x04, 0x00000000 }, - { 0x001a00, 1, 0x04, 0x00001111 }, - { 0x001a04, 7, 0x04, 0x00000000 }, - { 0x000d6c, 2, 0x04, 0xffff0000 }, - { 0x0010f8, 1, 0x04, 0x00001010 }, - { 0x000d80, 5, 0x04, 0x00000000 }, - { 0x000da0, 1, 0x04, 0x00000000 }, - { 0x0007a4, 2, 0x04, 0x00000000 }, - { 0x001508, 1, 0x04, 0x80000000 }, - { 0x00150c, 1, 0x04, 0x40000000 }, - { 0x001668, 1, 0x04, 0x00000000 }, - { 0x000318, 2, 0x04, 0x00000008 }, - { 0x000d9c, 1, 0x04, 0x00000001 }, - { 0x000ddc, 1, 0x04, 0x00000002 }, - { 0x000374, 1, 0x04, 0x00000000 }, - { 0x000378, 1, 0x04, 0x00000020 }, - { 0x0007dc, 1, 0x04, 0x00000000 }, - { 0x00074c, 1, 0x04, 0x00000055 }, - { 0x001420, 1, 0x04, 0x00000003 }, - { 0x0017bc, 2, 0x04, 0x00000000 }, - { 0x0017c4, 1, 0x04, 0x00000001 }, - { 0x001008, 1, 0x04, 0x00000008 }, - { 0x00100c, 1, 0x04, 0x00000040 }, - { 0x001010, 1, 0x04, 0x0000012c }, - { 0x000d60, 1, 0x04, 0x00000040 }, - { 0x00075c, 1, 0x04, 0x00000003 }, - { 0x001018, 1, 0x04, 0x00000020 }, - { 0x00101c, 1, 0x04, 0x00000001 }, - { 0x001020, 1, 0x04, 0x00000020 }, - { 0x001024, 1, 0x04, 0x00000001 }, - { 0x001444, 3, 0x04, 0x00000000 }, - { 0x000360, 1, 0x04, 0x20164010 }, - { 0x000364, 1, 0x04, 0x00000020 }, - { 0x000368, 1, 0x04, 0x00000000 }, - { 0x000de4, 1, 0x04, 0x00000000 }, - { 0x000204, 1, 0x04, 0x00000006 }, - { 0x000208, 1, 0x04, 0x00000000 }, - { 0x0002cc, 2, 0x04, 0x003fffff }, - { 0x001220, 1, 0x04, 0x00000005 }, - { 0x000fdc, 1, 0x04, 0x00000000 }, - { 0x000f98, 1, 0x04, 0x00400008 }, - { 0x001284, 1, 0x04, 0x08000080 }, - { 0x001450, 1, 0x04, 0x00400008 }, - { 0x001454, 1, 0x04, 0x08000080 }, - { 0x000214, 1, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nv108_grctx_pack_icmd[] = { + { nv108_grctx_init_icmd_0 }, {} }; -static struct nvc0_graph_init -nv108_grctx_init_unk40xx[] = { +static const struct nvc0_graph_init +nv108_grctx_init_fe_0[] = { { 0x404004, 8, 0x04, 0x00000000 }, { 0x404024, 1, 0x04, 0x0000e000 }, { 0x404028, 8, 0x04, 0x00000000 }, @@ -1132,8 +311,8 @@ nv108_grctx_init_unk40xx[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_unk58xx[] = { +static const struct nvc0_graph_init +nv108_grctx_init_ds_0[] = { { 0x405800, 1, 0x04, 0x0f8000bf }, { 0x405830, 1, 0x04, 0x02180648 }, { 0x405834, 1, 0x04, 0x08000000 }, @@ -1146,8 +325,10 @@ nv108_grctx_init_unk58xx[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_unk64xx[] = { +static const struct nvc0_graph_init +nv108_grctx_init_pd_0[] = { + { 0x406020, 1, 0x04, 0x034103c1 }, + { 0x406028, 4, 0x04, 0x00000001 }, { 0x4064a8, 1, 0x04, 0x00000000 }, { 0x4064ac, 1, 0x04, 0x00003fff }, { 0x4064b0, 3, 0x04, 0x00000000 }, @@ -1159,8 +340,8 @@ nv108_grctx_init_unk64xx[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_unk78xx[] = { +const struct nvc0_graph_init +nv108_grctx_init_rstr2d_0[] = { { 0x407804, 1, 0x04, 0x00000063 }, { 0x40780c, 1, 0x04, 0x0a418820 }, { 0x407810, 1, 0x04, 0x062080e6 }, @@ -1172,8 +353,8 @@ nv108_grctx_init_unk78xx[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_unk88xx[] = { +static const struct nvc0_graph_init +nv108_grctx_init_be_0[] = { { 0x408800, 1, 0x04, 0x32802a3c }, { 0x408804, 1, 0x04, 0x00000040 }, { 0x408808, 1, 0x04, 0x1003e005 }, @@ -1185,9 +366,23 @@ nv108_grctx_init_unk88xx[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_gpc_0[] = { - { 0x418380, 1, 0x04, 0x00000016 }, +static const struct nvc0_graph_pack +nv108_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nv108_grctx_init_fe_0 }, + { nvf0_grctx_init_pri_0 }, + { nve4_grctx_init_memfmt_0 }, + { nv108_grctx_init_ds_0 }, + { nvf0_grctx_init_cwd_0 }, + { nv108_grctx_init_pd_0 }, + { nv108_grctx_init_rstr2d_0 }, + { nve4_grctx_init_scc_0 }, + { nv108_grctx_init_be_0 }, + {} +}; + +const struct nvc0_graph_init +nv108_grctx_init_prop_0[] = { { 0x418400, 1, 0x04, 0x38005e00 }, { 0x418404, 1, 0x04, 0x71e0ffff }, { 0x41840c, 1, 0x04, 0x00001008 }, @@ -1196,11 +391,21 @@ nv108_grctx_init_gpc_0[] = { { 0x418450, 6, 0x04, 0x00000000 }, { 0x418468, 1, 0x04, 0x00000001 }, { 0x41846c, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nv108_grctx_init_gpc_unk_1[] = { { 0x418600, 1, 0x04, 0x0000007f }, { 0x418684, 1, 0x04, 0x0000001f }, { 0x418700, 1, 0x04, 0x00000002 }, { 0x418704, 2, 0x04, 0x00000080 }, { 0x41870c, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nv108_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x7006863a }, { 0x418808, 1, 0x04, 0x00000000 }, { 0x41880c, 1, 0x04, 0x00000030 }, @@ -1211,10 +416,11 @@ nv108_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x20100058 }, - { 0x41891c, 1, 0x04, 0x00ff00ff }, - { 0x418924, 1, 0x04, 0x00000000 }, - { 0x418928, 1, 0x04, 0x00ffff00 }, - { 0x41892c, 1, 0x04, 0x0000ff00 }, + {} +}; + +const struct nvc0_graph_init +nv108_grctx_init_crstr_0[] = { { 0x418b00, 1, 0x04, 0x0000001e }, { 0x418b08, 1, 0x04, 0x0a418820 }, { 0x418b0c, 1, 0x04, 0x062080e6 }, @@ -1223,24 +429,36 @@ nv108_grctx_init_gpc_0[] = { { 0x418b18, 1, 0x04, 0x0a418820 }, { 0x418b1c, 1, 0x04, 0x000000e6 }, { 0x418bb8, 1, 0x04, 0x00000103 }, + {} +}; + +static const struct nvc0_graph_init +nv108_grctx_init_gpm_0[] = { { 0x418c08, 1, 0x04, 0x00000001 }, { 0x418c10, 8, 0x04, 0x00000000 }, { 0x418c40, 1, 0x04, 0xffffffff }, { 0x418c6c, 1, 0x04, 0x00000001 }, { 0x418c80, 1, 0x04, 0x2020000c }, { 0x418c8c, 1, 0x04, 0x00000001 }, - { 0x418d24, 1, 0x04, 0x00000000 }, - { 0x419000, 1, 0x04, 0x00000780 }, - { 0x419004, 2, 0x04, 0x00000000 }, - { 0x419014, 1, 0x04, 0x00000004 }, {} }; -static struct nvc0_graph_init -nv108_grctx_init_tpc[] = { - { 0x419848, 1, 0x04, 0x00000000 }, - { 0x419864, 1, 0x04, 0x00000129 }, - { 0x419888, 1, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nv108_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nv108_grctx_init_prop_0 }, + { nv108_grctx_init_gpc_unk_1 }, + { nv108_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nv108_grctx_init_crstr_0 }, + { nv108_grctx_init_gpm_0 }, + { nvf0_grctx_init_gpc_unk_2 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +static const struct nvc0_graph_init +nv108_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000100f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000421 }, @@ -1251,14 +469,11 @@ nv108_grctx_init_tpc[] = { { 0x419a20, 1, 0x04, 0x00000800 }, { 0x419a30, 1, 0x04, 0x00000001 }, { 0x419ac4, 1, 0x04, 0x0037f440 }, - { 0x419c00, 1, 0x04, 0x0000001a }, - { 0x419c04, 1, 0x04, 0x80000006 }, - { 0x419c08, 1, 0x04, 0x00000002 }, - { 0x419c20, 1, 0x04, 0x00000000 }, - { 0x419c24, 1, 0x04, 0x00084210 }, - { 0x419c28, 1, 0x04, 0x3efbefbe }, - { 0x419ce8, 1, 0x04, 0x00000000 }, - { 0x419cf4, 1, 0x04, 0x00000203 }, + {} +}; + +static const struct nvc0_graph_init +nv108_grctx_init_sm_0[] = { { 0x419e04, 1, 0x04, 0x00000000 }, { 0x419e08, 1, 0x04, 0x0000001d }, { 0x419e0c, 1, 0x04, 0x00000000 }, @@ -1272,7 +487,7 @@ nv108_grctx_init_tpc[] = { { 0x419e68, 1, 0x04, 0x00000002 }, { 0x419e6c, 12, 0x04, 0x00000000 }, { 0x419eac, 1, 0x04, 0x00001f8f }, - { 0x419eb0, 1, 0x04, 0x0db00da0 }, + { 0x419eb0, 1, 0x04, 0x0db00d2f }, { 0x419eb8, 1, 0x04, 0x00000000 }, { 0x419ec8, 1, 0x04, 0x0001304f }, { 0x419f30, 4, 0x04, 0x00000000 }, @@ -1285,25 +500,37 @@ nv108_grctx_init_tpc[] = { {} }; -static struct nvc0_graph_init -nv108_grctx_init_unk[] = { - { 0x41be24, 1, 0x04, 0x00000006 }, +static const struct nvc0_graph_pack +nv108_grctx_pack_tpc[] = { + { nvd7_grctx_init_pe_0 }, + { nv108_grctx_init_tex_0 }, + { nvf0_grctx_init_mpc_0 }, + { nvf0_grctx_init_l1c_0 }, + { nv108_grctx_init_sm_0 }, + {} +}; + +static const struct nvc0_graph_init +nv108_grctx_init_cbm_0[] = { { 0x41bec0, 1, 0x04, 0x10000000 }, { 0x41bec4, 1, 0x04, 0x00037f7f }, { 0x41bee4, 1, 0x04, 0x00000000 }, { 0x41bef0, 1, 0x04, 0x000003ff }, - { 0x41bf00, 1, 0x04, 0x0a418820 }, - { 0x41bf04, 1, 0x04, 0x062080e6 }, - { 0x41bf08, 1, 0x04, 0x020398a4 }, - { 0x41bf0c, 1, 0x04, 0x0e629062 }, - { 0x41bf10, 1, 0x04, 0x0a418820 }, - { 0x41bf14, 1, 0x04, 0x000000e6 }, - { 0x41bfd0, 1, 0x04, 0x00900103 }, - { 0x41bfe0, 1, 0x04, 0x00400001 }, - { 0x41bfe4, 1, 0x04, 0x00000000 }, {} }; +static const struct nvc0_graph_pack +nv108_grctx_pack_ppc[] = { + { nve4_grctx_init_pes_0 }, + { nv108_grctx_init_cbm_0 }, + { nvd7_grctx_init_wwdx_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + static void nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { @@ -1318,10 +545,12 @@ nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) 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); @@ -1346,47 +575,6 @@ nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) mmio_list(0x17e920, 0x00090d08, 0, 0); } -static struct nvc0_graph_init * -nv108_grctx_init_hub[] = { - nvc0_grctx_init_base, - nv108_grctx_init_unk40xx, - nvf0_grctx_init_unk44xx, - nve4_grctx_init_unk46xx, - nve4_grctx_init_unk47xx, - nv108_grctx_init_unk58xx, - nvf0_grctx_init_unk5bxx, - nvf0_grctx_init_unk60xx, - nv108_grctx_init_unk64xx, - nv108_grctx_init_unk78xx, - nve4_grctx_init_unk80xx, - nv108_grctx_init_unk88xx, - NULL -}; - -struct nvc0_graph_init * -nv108_grctx_init_gpc[] = { - nv108_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nv108_grctx_init_tpc, - nv108_grctx_init_unk, - NULL -}; - -struct nvc0_graph_init -nv108_grctx_init_mthd_magic[] = { - { 0x3410, 1, 0x04, 0x8e0e2006 }, - { 0x3414, 1, 0x04, 0x00000038 }, - {} -}; - -static struct nvc0_graph_mthd -nv108_grctx_init_mthd[] = { - { 0xa197, nv108_grctx_init_a197, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x902d, nv108_grctx_init_mthd_magic, }, - {} -}; - struct nouveau_oclass * nv108_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0x08), @@ -1398,11 +586,14 @@ nv108_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nve4_grctx_generate_main, - .mods = nv108_grctx_generate_mods, - .unkn = nve4_grctx_generate_unkn, - .hub = nv108_grctx_init_hub, - .gpc = nv108_grctx_init_gpc, - .icmd = nv108_grctx_init_icmd, - .mthd = nv108_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nv108_grctx_pack_tpc, + .ppc = nv108_grctx_pack_ppc, + .icmd = nv108_grctx_pack_icmd, + .mthd = nvf0_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c index fe67415c3e1..833a96508c4 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c @@ -22,10 +22,14 @@ * Authors: Ben Skeggs */ -#include "nvc0.h" +#include "ctxnvc0.h" -struct nvc0_graph_init -nvc0_grctx_init_icmd[] = { +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nvc0_grctx_init_icmd_0[] = { { 0x001000, 1, 0x01, 0x00000004 }, { 0x0000a9, 1, 0x01, 0x0000ffff }, { 0x000038, 1, 0x01, 0x0fac6881 }, @@ -140,8 +144,7 @@ nvc0_grctx_init_icmd[] = { { 0x000586, 1, 0x01, 0x00000040 }, { 0x000582, 2, 0x01, 0x00000080 }, { 0x0005c2, 1, 0x01, 0x00000001 }, - { 0x000638, 1, 0x01, 0x00000001 }, - { 0x000639, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, { 0x00063a, 1, 0x01, 0x00000002 }, { 0x00063b, 2, 0x01, 0x00000001 }, { 0x00063d, 1, 0x01, 0x00000002 }, @@ -201,15 +204,13 @@ nvc0_grctx_init_icmd[] = { { 0x000787, 1, 0x01, 0x000000cf }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x000836, 1, 0x01, 0x00000001 }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x00080c, 1, 0x01, 0x00000002 }, { 0x00080d, 2, 0x01, 0x00000100 }, @@ -235,14 +236,12 @@ nvc0_grctx_init_icmd[] = { { 0x0006b1, 1, 0x01, 0x00000011 }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x01e100, 1, 0x01, 0x00000001 }, { 0x001000, 1, 0x01, 0x00000014 }, @@ -267,8 +266,14 @@ nvc0_grctx_init_icmd[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_9097[] = { +const struct nvc0_graph_pack +nvc0_grctx_pack_icmd[] = { + { nvc0_grctx_init_icmd_0 }, + {} +}; + +static const struct nvc0_graph_init +nvc0_grctx_init_9097_0[] = { { 0x000800, 8, 0x40, 0x00000000 }, { 0x000804, 8, 0x40, 0x00000000 }, { 0x000808, 8, 0x40, 0x00000400 }, @@ -516,8 +521,7 @@ nvc0_grctx_init_9097[] = { { 0x001350, 1, 0x04, 0x00000002 }, { 0x001358, 1, 0x04, 0x00000001 }, { 0x0012e4, 1, 0x04, 0x00000000 }, - { 0x00131c, 1, 0x04, 0x00000000 }, - { 0x001320, 3, 0x04, 0x00000000 }, + { 0x00131c, 4, 0x04, 0x00000000 }, { 0x0019c0, 1, 0x04, 0x00000000 }, { 0x001140, 1, 0x04, 0x00000000 }, { 0x0019c4, 1, 0x04, 0x00000000 }, @@ -571,8 +575,8 @@ nvc0_grctx_init_9097[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_902d[] = { +const struct nvc0_graph_init +nvc0_grctx_init_902d_0[] = { { 0x000200, 1, 0x04, 0x000000cf }, { 0x000204, 1, 0x04, 0x00000001 }, { 0x000208, 1, 0x04, 0x00000020 }, @@ -590,8 +594,8 @@ nvc0_grctx_init_902d[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_9039[] = { +const struct nvc0_graph_init +nvc0_grctx_init_9039_0[] = { { 0x00030c, 3, 0x04, 0x00000000 }, { 0x000320, 1, 0x04, 0x00000000 }, { 0x000238, 2, 0x04, 0x00000000 }, @@ -599,8 +603,8 @@ nvc0_grctx_init_9039[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_90c0[] = { +const struct nvc0_graph_init +nvc0_grctx_init_90c0_0[] = { { 0x00270c, 8, 0x20, 0x00000000 }, { 0x00030c, 1, 0x04, 0x00000001 }, { 0x001944, 1, 0x04, 0x00000000 }, @@ -617,38 +621,44 @@ nvc0_grctx_init_90c0[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_base[] = { +const struct nvc0_graph_pack +nvc0_grctx_pack_mthd[] = { + { nvc0_grctx_init_9097_0, 0x9097 }, + { nvc0_grctx_init_902d_0, 0x902d }, + { nvc0_grctx_init_9039_0, 0x9039 }, + { nvc0_grctx_init_90c0_0, 0x90c0 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_main_0[] = { { 0x400204, 2, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk40xx[] = { - { 0x404004, 10, 0x04, 0x00000000 }, +const struct nvc0_graph_init +nvc0_grctx_init_fe_0[] = { + { 0x404004, 11, 0x04, 0x00000000 }, { 0x404044, 1, 0x04, 0x00000000 }, - { 0x404094, 1, 0x04, 0x00000000 }, - { 0x404098, 12, 0x04, 0x00000000 }, + { 0x404094, 13, 0x04, 0x00000000 }, { 0x4040c8, 1, 0x04, 0xf0000087 }, { 0x4040d0, 6, 0x04, 0x00000000 }, { 0x4040e8, 1, 0x04, 0x00001000 }, { 0x4040f8, 1, 0x04, 0x00000000 }, - { 0x404130, 1, 0x04, 0x00000000 }, - { 0x404134, 1, 0x04, 0x00000000 }, + { 0x404130, 2, 0x04, 0x00000000 }, { 0x404138, 1, 0x04, 0x20000040 }, { 0x404150, 1, 0x04, 0x0000002e }, { 0x404154, 1, 0x04, 0x00000400 }, { 0x404158, 1, 0x04, 0x00000200 }, { 0x404164, 1, 0x04, 0x00000055 }, { 0x404168, 1, 0x04, 0x00000000 }, - { 0x404174, 1, 0x04, 0x00000000 }, - { 0x404178, 2, 0x04, 0x00000000 }, + { 0x404174, 3, 0x04, 0x00000000 }, { 0x404200, 8, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk44xx[] = { +const struct nvc0_graph_init +nvc0_grctx_init_pri_0[] = { { 0x404404, 14, 0x04, 0x00000000 }, { 0x404460, 2, 0x04, 0x00000000 }, { 0x404468, 1, 0x04, 0x00ffffff }, @@ -658,8 +668,8 @@ nvc0_grctx_init_unk44xx[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk46xx[] = { +const struct nvc0_graph_init +nvc0_grctx_init_memfmt_0[] = { { 0x404604, 1, 0x04, 0x00000015 }, { 0x404608, 1, 0x04, 0x00000000 }, { 0x40460c, 1, 0x04, 0x00002e00 }, @@ -674,19 +684,14 @@ nvc0_grctx_init_unk46xx[] = { { 0x4046a0, 1, 0x04, 0x007f0080 }, { 0x4046a4, 18, 0x04, 0x00000000 }, { 0x4046f0, 2, 0x04, 0x00000000 }, - {} -}; - -struct nvc0_graph_init -nvc0_grctx_init_unk47xx[] = { { 0x404700, 13, 0x04, 0x00000000 }, { 0x404734, 1, 0x04, 0x00000100 }, { 0x404738, 8, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk58xx[] = { +static const struct nvc0_graph_init +nvc0_grctx_init_ds_0[] = { { 0x405800, 1, 0x04, 0x078000bf }, { 0x405830, 1, 0x04, 0x02180000 }, { 0x405834, 2, 0x04, 0x00000000 }, @@ -697,23 +702,18 @@ nvc0_grctx_init_unk58xx[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk60xx[] = { +static const struct nvc0_graph_init +nvc0_grctx_init_pd_0[] = { { 0x406020, 1, 0x04, 0x000103c1 }, { 0x406028, 4, 0x04, 0x00000001 }, - {} -}; - -struct nvc0_graph_init -nvc0_grctx_init_unk64xx[] = { { 0x4064a8, 1, 0x04, 0x00000000 }, { 0x4064ac, 1, 0x04, 0x00003fff }, { 0x4064b4, 2, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk78xx[] = { +const struct nvc0_graph_init +nvc0_grctx_init_rstr2d_0[] = { { 0x407804, 1, 0x04, 0x00000023 }, { 0x40780c, 1, 0x04, 0x0a418820 }, { 0x407810, 1, 0x04, 0x062080e6 }, @@ -725,8 +725,8 @@ nvc0_grctx_init_unk78xx[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_unk80xx[] = { +const struct nvc0_graph_init +nvc0_grctx_init_scc_0[] = { { 0x408000, 2, 0x04, 0x00000000 }, { 0x408008, 1, 0x04, 0x00000018 }, { 0x40800c, 2, 0x04, 0x00000000 }, @@ -736,8 +736,8 @@ nvc0_grctx_init_unk80xx[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_rop[] = { +static const struct nvc0_graph_init +nvc0_grctx_init_be_0[] = { { 0x408800, 1, 0x04, 0x02802a3c }, { 0x408804, 1, 0x04, 0x00000040 }, { 0x408808, 1, 0x04, 0x0003e00d }, @@ -748,9 +748,28 @@ nvc0_grctx_init_rop[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_gpc_0[] = { +const struct nvc0_graph_pack +nvc0_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nvc0_grctx_init_fe_0 }, + { nvc0_grctx_init_pri_0 }, + { nvc0_grctx_init_memfmt_0 }, + { nvc0_grctx_init_ds_0 }, + { nvc0_grctx_init_pd_0 }, + { nvc0_grctx_init_rstr2d_0 }, + { nvc0_grctx_init_scc_0 }, + { nvc0_grctx_init_be_0 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_gpc_unk_0[] = { { 0x418380, 1, 0x04, 0x00000016 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_prop_0[] = { { 0x418400, 1, 0x04, 0x38004e00 }, { 0x418404, 1, 0x04, 0x71e0ffff }, { 0x418408, 1, 0x04, 0x00000000 }, @@ -760,6 +779,11 @@ nvc0_grctx_init_gpc_0[] = { { 0x418450, 6, 0x04, 0x00000000 }, { 0x418468, 1, 0x04, 0x00000001 }, { 0x41846c, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_gpc_unk_1[] = { { 0x418600, 1, 0x04, 0x0000001f }, { 0x418684, 1, 0x04, 0x0000000f }, { 0x418700, 1, 0x04, 0x00000002 }, @@ -767,6 +791,11 @@ nvc0_grctx_init_gpc_0[] = { { 0x418708, 1, 0x04, 0x00000000 }, { 0x41870c, 1, 0x04, 0x07c80000 }, { 0x418710, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvc0_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x0006860a }, { 0x418808, 3, 0x04, 0x00000000 }, { 0x418828, 1, 0x04, 0x00008442 }, @@ -775,10 +804,20 @@ nvc0_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x00100000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_zcull_0[] = { { 0x41891c, 1, 0x04, 0x00ff00ff }, { 0x418924, 1, 0x04, 0x00000000 }, { 0x418928, 1, 0x04, 0x00ffff00 }, { 0x41892c, 1, 0x04, 0x0000ff00 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_crstr_0[] = { { 0x418b00, 1, 0x04, 0x00000000 }, { 0x418b08, 1, 0x04, 0x0a418820 }, { 0x418b0c, 1, 0x04, 0x062080e6 }, @@ -787,18 +826,41 @@ nvc0_grctx_init_gpc_0[] = { { 0x418b18, 1, 0x04, 0x0a418820 }, { 0x418b1c, 1, 0x04, 0x000000e6 }, { 0x418bb8, 1, 0x04, 0x00000103 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_gpm_0[] = { { 0x418c08, 1, 0x04, 0x00000001 }, { 0x418c10, 8, 0x04, 0x00000000 }, { 0x418c80, 1, 0x04, 0x20200004 }, { 0x418c8c, 1, 0x04, 0x00000001 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_gcc_0[] = { { 0x419000, 1, 0x04, 0x00000780 }, { 0x419004, 2, 0x04, 0x00000000 }, { 0x419014, 1, 0x04, 0x00000004 }, {} }; -struct nvc0_graph_init -nvc0_grctx_init_gpc_1[] = { +const struct nvc0_graph_pack +nvc0_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvc0_grctx_init_prop_0 }, + { nvc0_grctx_init_gpc_unk_1 }, + { nvc0_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvc0_grctx_init_crstr_0 }, + { nvc0_grctx_init_gpm_0 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +static const struct nvc0_graph_init +nvc0_grctx_init_zcullr_0[] = { { 0x418a00, 3, 0x04, 0x00000000 }, { 0x418a0c, 1, 0x04, 0x00010000 }, { 0x418a10, 3, 0x04, 0x00000000 }, @@ -826,19 +888,35 @@ nvc0_grctx_init_gpc_1[] = { {} }; -struct nvc0_graph_init -nvc0_grctx_init_tpc[] = { +const struct nvc0_graph_pack +nvc0_grctx_pack_zcull[] = { + { nvc0_grctx_init_zcullr_0 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_pe_0[] = { { 0x419818, 1, 0x04, 0x00000000 }, { 0x41983c, 1, 0x04, 0x00038bc7 }, { 0x419848, 1, 0x04, 0x00000000 }, { 0x419864, 1, 0x04, 0x0000012a }, { 0x419888, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvc0_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000001f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000023 }, { 0x419a0c, 1, 0x04, 0x00020000 }, { 0x419a10, 1, 0x04, 0x00000000 }, { 0x419a14, 1, 0x04, 0x00000200 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_wwdx_0[] = { { 0x419b00, 1, 0x04, 0x0a418820 }, { 0x419b04, 1, 0x04, 0x062080e6 }, { 0x419b08, 1, 0x04, 0x020398a4 }, @@ -848,15 +926,35 @@ nvc0_grctx_init_tpc[] = { { 0x419bd0, 1, 0x04, 0x00900103 }, { 0x419be0, 1, 0x04, 0x00000001 }, { 0x419be4, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_mpc_0[] = { { 0x419c00, 1, 0x04, 0x00000002 }, { 0x419c04, 1, 0x04, 0x00000006 }, { 0x419c08, 1, 0x04, 0x00000002 }, { 0x419c20, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvc0_grctx_init_l1c_0[] = { { 0x419cb0, 1, 0x04, 0x00060048 }, { 0x419ce8, 1, 0x04, 0x00000000 }, { 0x419cf4, 1, 0x04, 0x00000183 }, + {} +}; + +const struct nvc0_graph_init +nvc0_grctx_init_tpccs_0[] = { { 0x419d20, 1, 0x04, 0x02180000 }, { 0x419d24, 1, 0x04, 0x00001fff }, + {} +}; + +static const struct nvc0_graph_init +nvc0_grctx_init_sm_0[] = { { 0x419e04, 3, 0x04, 0x00000000 }, { 0x419e10, 1, 0x04, 0x00000002 }, { 0x419e44, 1, 0x04, 0x001beff2 }, @@ -868,6 +966,22 @@ nvc0_grctx_init_tpc[] = { {} }; +const struct nvc0_graph_pack +nvc0_grctx_pack_tpc[] = { + { nvc0_grctx_init_pe_0 }, + { nvc0_grctx_init_tex_0 }, + { nvc0_grctx_init_wwdx_0 }, + { nvc0_grctx_init_mpc_0 }, + { nvc0_grctx_init_l1c_0 }, + { nvc0_grctx_init_tpccs_0 }, + { nvc0_grctx_init_sm_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + void nvc0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { @@ -1055,14 +1169,14 @@ void nvc0_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); - for (i = 0; oclass->hub[i]; i++) - nvc0_graph_mmio(priv, oclass->hub[i]); - for (i = 0; oclass->gpc[i]; i++) - nvc0_graph_mmio(priv, oclass->gpc[i]); + nvc0_graph_mmio(priv, oclass->hub); + nvc0_graph_mmio(priv, oclass->gpc); + nvc0_graph_mmio(priv, oclass->zcull); + nvc0_graph_mmio(priv, oclass->tpc); + nvc0_graph_mmio(priv, oclass->ppc); nv_wr32(priv, 0x404154, 0x00000000); @@ -1182,46 +1296,6 @@ done: return ret; } -struct nvc0_graph_init * -nvc0_grctx_init_hub[] = { - nvc0_grctx_init_base, - nvc0_grctx_init_unk40xx, - nvc0_grctx_init_unk44xx, - nvc0_grctx_init_unk46xx, - nvc0_grctx_init_unk47xx, - nvc0_grctx_init_unk58xx, - nvc0_grctx_init_unk60xx, - nvc0_grctx_init_unk64xx, - nvc0_grctx_init_unk78xx, - nvc0_grctx_init_unk80xx, - nvc0_grctx_init_rop, - NULL -}; - -static struct nvc0_graph_init * -nvc0_grctx_init_gpc[] = { - nvc0_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvc0_grctx_init_tpc, - NULL -}; - -struct nvc0_graph_init -nvc0_grctx_init_mthd_magic[] = { - { 0x3410, 1, 0x04, 0x00000000 }, - {} -}; - -struct nvc0_graph_mthd -nvc0_grctx_init_mthd[] = { - { 0x9097, nvc0_grctx_init_9097, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x9039, nvc0_grctx_init_9039, }, - { 0x90c0, nvc0_grctx_init_90c0, }, - { 0x902d, nvc0_grctx_init_mthd_magic, }, - {} -}; - struct nouveau_oclass * nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xc0), @@ -1233,11 +1307,13 @@ nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nvc0_grctx_generate_main, - .mods = nvc0_grctx_generate_mods, - .unkn = nvc0_grctx_generate_unkn, - .hub = nvc0_grctx_init_hub, - .gpc = nvc0_grctx_init_gpc, - .icmd = nvc0_grctx_init_icmd, - .mthd = nvc0_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvc0_grctx_pack_tpc, + .icmd = nvc0_grctx_pack_icmd, + .mthd = nvc0_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h new file mode 100644 index 00000000000..8da8b627b9d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h @@ -0,0 +1,179 @@ +#ifndef __NVKM_GRCTX_NVC0_H__ +#define __NVKM_GRCTX_NVC0_H__ + +#include "nvc0.h" + +struct nvc0_grctx { + struct nvc0_graph_priv *priv; + struct nvc0_graph_data *data; + struct nvc0_graph_mmio *mmio; + int buffer_nr; + u64 buffer[4]; + u64 addr; +}; + +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; + const struct nvc0_graph_pack *gpc; + const struct nvc0_graph_pack *zcull; + const struct nvc0_graph_pack *tpc; + const struct nvc0_graph_pack *ppc; + /* indirect context data, generated with icmds/mthds */ + const struct nvc0_graph_pack *icmd; + const struct nvc0_graph_pack *mthd; +}; + +#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) + +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_unkn(struct nvc0_graph_priv *); +void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *); +void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *); +void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *); +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_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; +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_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 *nv108_grctx_oclass; +extern struct nouveau_oclass *gm107_grctx_oclass; + +/* context init value lists */ + +extern const struct nvc0_graph_pack nvc0_grctx_pack_icmd[]; + +extern const struct nvc0_graph_pack nvc0_grctx_pack_mthd[]; +extern const struct nvc0_graph_init nvc0_grctx_init_902d_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_9039_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_90c0_0[]; + +extern const struct nvc0_graph_pack nvc0_grctx_pack_hub[]; +extern const struct nvc0_graph_init nvc0_grctx_init_main_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_fe_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_pri_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_memfmt_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_rstr2d_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_scc_0[]; + +extern const struct nvc0_graph_pack nvc0_grctx_pack_gpc[]; +extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_prop_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_1[]; +extern const struct nvc0_graph_init nvc0_grctx_init_zcull_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_crstr_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_gpm_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_gcc_0[]; + +extern const struct nvc0_graph_pack nvc0_grctx_pack_zcull[]; + +extern const struct nvc0_graph_pack nvc0_grctx_pack_tpc[]; +extern const struct nvc0_graph_init nvc0_grctx_init_pe_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_wwdx_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_mpc_0[]; +extern const struct nvc0_graph_init nvc0_grctx_init_tpccs_0[]; + +extern const struct nvc0_graph_init nvc4_grctx_init_tex_0[]; +extern const struct nvc0_graph_init nvc4_grctx_init_l1c_0[]; +extern const struct nvc0_graph_init nvc4_grctx_init_sm_0[]; + +extern const struct nvc0_graph_init nvc1_grctx_init_9097_0[]; + +extern const struct nvc0_graph_init nvc1_grctx_init_gpm_0[]; + +extern const struct nvc0_graph_init nvc1_grctx_init_pe_0[]; +extern const struct nvc0_graph_init nvc1_grctx_init_wwdx_0[]; +extern const struct nvc0_graph_init nvc1_grctx_init_tpccs_0[]; + +extern const struct nvc0_graph_init nvc8_grctx_init_9197_0[]; +extern const struct nvc0_graph_init nvc8_grctx_init_9297_0[]; + +extern const struct nvc0_graph_pack nvd9_grctx_pack_icmd[]; + +extern const struct nvc0_graph_pack nvd9_grctx_pack_mthd[]; + +extern const struct nvc0_graph_init nvd9_grctx_init_fe_0[]; +extern const struct nvc0_graph_init nvd9_grctx_init_be_0[]; + +extern const struct nvc0_graph_init nvd9_grctx_init_prop_0[]; +extern const struct nvc0_graph_init nvd9_grctx_init_gpc_unk_1[]; +extern const struct nvc0_graph_init nvd9_grctx_init_crstr_0[]; + +extern const struct nvc0_graph_init nvd9_grctx_init_sm_0[]; + +extern const struct nvc0_graph_init nvd7_grctx_init_pe_0[]; + +extern const struct nvc0_graph_init nvd7_grctx_init_wwdx_0[]; + +extern const struct nvc0_graph_init nve4_grctx_init_memfmt_0[]; +extern const struct nvc0_graph_init nve4_grctx_init_ds_0[]; +extern const struct nvc0_graph_init nve4_grctx_init_scc_0[]; + +extern const struct nvc0_graph_init nve4_grctx_init_gpm_0[]; + +extern const struct nvc0_graph_init nve4_grctx_init_pes_0[]; + +extern const struct nvc0_graph_pack nve4_grctx_pack_hub[]; +extern const struct nvc0_graph_pack nve4_grctx_pack_gpc[]; +extern const struct nvc0_graph_pack nve4_grctx_pack_tpc[]; +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_mthd[]; + +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_init nvf0_grctx_init_gpc_unk_2[]; + +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_init nv108_grctx_init_rstr2d_0[]; + +extern const struct nvc0_graph_init nv108_grctx_init_prop_0[]; +extern const struct nvc0_graph_init nv108_grctx_init_crstr_0[]; + + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c index 71b4283f7fa..24a92c569c0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c @@ -22,10 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -static struct nvc0_graph_init -nvc1_grctx_init_icmd[] = { +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nvc1_grctx_init_icmd_0[] = { { 0x001000, 1, 0x01, 0x00000004 }, { 0x0000a9, 1, 0x01, 0x0000ffff }, { 0x000038, 1, 0x01, 0x0fac6881 }, @@ -141,8 +145,7 @@ nvc1_grctx_init_icmd[] = { { 0x000586, 1, 0x01, 0x00000040 }, { 0x000582, 2, 0x01, 0x00000080 }, { 0x0005c2, 1, 0x01, 0x00000001 }, - { 0x000638, 1, 0x01, 0x00000001 }, - { 0x000639, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, { 0x00063a, 1, 0x01, 0x00000002 }, { 0x00063b, 2, 0x01, 0x00000001 }, { 0x00063d, 1, 0x01, 0x00000002 }, @@ -202,15 +205,13 @@ nvc1_grctx_init_icmd[] = { { 0x000787, 1, 0x01, 0x000000cf }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x000836, 1, 0x01, 0x00000001 }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x00080c, 1, 0x01, 0x00000002 }, { 0x00080d, 2, 0x01, 0x00000100 }, @@ -236,14 +237,12 @@ nvc1_grctx_init_icmd[] = { { 0x0006b1, 1, 0x01, 0x00000011 }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x01e100, 1, 0x01, 0x00000001 }, { 0x001000, 1, 0x01, 0x00000014 }, @@ -268,8 +267,14 @@ nvc1_grctx_init_icmd[] = { {} }; -struct nvc0_graph_init -nvc1_grctx_init_9097[] = { +static const struct nvc0_graph_pack +nvc1_grctx_pack_icmd[] = { + { nvc1_grctx_init_icmd_0 }, + {} +}; + +const struct nvc0_graph_init +nvc1_grctx_init_9097_0[] = { { 0x000800, 8, 0x40, 0x00000000 }, { 0x000804, 8, 0x40, 0x00000000 }, { 0x000808, 8, 0x40, 0x00000400 }, @@ -516,8 +521,7 @@ nvc1_grctx_init_9097[] = { { 0x001350, 1, 0x04, 0x00000002 }, { 0x001358, 1, 0x04, 0x00000001 }, { 0x0012e4, 1, 0x04, 0x00000000 }, - { 0x00131c, 1, 0x04, 0x00000000 }, - { 0x001320, 3, 0x04, 0x00000000 }, + { 0x00131c, 4, 0x04, 0x00000000 }, { 0x0019c0, 1, 0x04, 0x00000000 }, { 0x001140, 1, 0x04, 0x00000000 }, { 0x0019c4, 1, 0x04, 0x00000000 }, @@ -571,15 +575,25 @@ nvc1_grctx_init_9097[] = { {} }; -static struct nvc0_graph_init -nvc1_grctx_init_9197[] = { +static const struct nvc0_graph_init +nvc1_grctx_init_9197_0[] = { { 0x003400, 128, 0x04, 0x00000000 }, { 0x0002e4, 1, 0x04, 0x0000b001 }, {} }; -static struct nvc0_graph_init -nvc1_grctx_init_unk58xx[] = { +static const struct nvc0_graph_pack +nvc1_grctx_pack_mthd[] = { + { nvc1_grctx_init_9097_0, 0x9097 }, + { nvc1_grctx_init_9197_0, 0x9197 }, + { nvc0_grctx_init_902d_0, 0x902d }, + { nvc0_grctx_init_9039_0, 0x9039 }, + { nvc0_grctx_init_90c0_0, 0x90c0 }, + {} +}; + +static const struct nvc0_graph_init +nvc1_grctx_init_ds_0[] = { { 0x405800, 1, 0x04, 0x0f8000bf }, { 0x405830, 1, 0x04, 0x02180218 }, { 0x405834, 2, 0x04, 0x00000000 }, @@ -590,8 +604,20 @@ nvc1_grctx_init_unk58xx[] = { {} }; -static struct nvc0_graph_init -nvc1_grctx_init_rop[] = { +static const struct nvc0_graph_init +nvc1_grctx_init_pd_0[] = { + { 0x406020, 1, 0x04, 0x000103c1 }, + { 0x406028, 4, 0x04, 0x00000001 }, + { 0x4064a8, 1, 0x04, 0x00000000 }, + { 0x4064ac, 1, 0x04, 0x00003fff }, + { 0x4064b4, 2, 0x04, 0x00000000 }, + { 0x4064c0, 1, 0x04, 0x80140078 }, + { 0x4064c4, 1, 0x04, 0x0086ffff }, + {} +}; + +static const struct nvc0_graph_init +nvc1_grctx_init_be_0[] = { { 0x408800, 1, 0x04, 0x02802a3c }, { 0x408804, 1, 0x04, 0x00000040 }, { 0x408808, 1, 0x04, 0x1003e005 }, @@ -602,25 +628,22 @@ nvc1_grctx_init_rop[] = { {} }; -static struct nvc0_graph_init -nvc1_grctx_init_gpc_0[] = { - { 0x418380, 1, 0x04, 0x00000016 }, - { 0x418400, 1, 0x04, 0x38004e00 }, - { 0x418404, 1, 0x04, 0x71e0ffff }, - { 0x418408, 1, 0x04, 0x00000000 }, - { 0x41840c, 1, 0x04, 0x00001008 }, - { 0x418410, 1, 0x04, 0x0fff0fff }, - { 0x418414, 1, 0x04, 0x00200fff }, - { 0x418450, 6, 0x04, 0x00000000 }, - { 0x418468, 1, 0x04, 0x00000001 }, - { 0x41846c, 2, 0x04, 0x00000000 }, - { 0x418600, 1, 0x04, 0x0000001f }, - { 0x418684, 1, 0x04, 0x0000000f }, - { 0x418700, 1, 0x04, 0x00000002 }, - { 0x418704, 1, 0x04, 0x00000080 }, - { 0x418708, 1, 0x04, 0x00000000 }, - { 0x41870c, 1, 0x04, 0x07c80000 }, - { 0x418710, 1, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nvc1_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nvc0_grctx_init_fe_0 }, + { nvc0_grctx_init_pri_0 }, + { nvc0_grctx_init_memfmt_0 }, + { nvc1_grctx_init_ds_0 }, + { nvc1_grctx_init_pd_0 }, + { nvc0_grctx_init_rstr2d_0 }, + { nvc0_grctx_init_scc_0 }, + { nvc1_grctx_init_be_0 }, + {} +}; + +static const struct nvc0_graph_init +nvc1_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x0006860a }, { 0x418808, 3, 0x04, 0x00000000 }, { 0x418828, 1, 0x04, 0x00008442 }, @@ -629,69 +652,44 @@ nvc1_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x00100018 }, - { 0x41891c, 1, 0x04, 0x00ff00ff }, - { 0x418924, 1, 0x04, 0x00000000 }, - { 0x418928, 1, 0x04, 0x00ffff00 }, - { 0x41892c, 1, 0x04, 0x0000ff00 }, - { 0x418a00, 3, 0x04, 0x00000000 }, - { 0x418a0c, 1, 0x04, 0x00010000 }, - { 0x418a10, 3, 0x04, 0x00000000 }, - { 0x418a20, 3, 0x04, 0x00000000 }, - { 0x418a2c, 1, 0x04, 0x00010000 }, - { 0x418a30, 3, 0x04, 0x00000000 }, - { 0x418a40, 3, 0x04, 0x00000000 }, - { 0x418a4c, 1, 0x04, 0x00010000 }, - { 0x418a50, 3, 0x04, 0x00000000 }, - { 0x418a60, 3, 0x04, 0x00000000 }, - { 0x418a6c, 1, 0x04, 0x00010000 }, - { 0x418a70, 3, 0x04, 0x00000000 }, - { 0x418a80, 3, 0x04, 0x00000000 }, - { 0x418a8c, 1, 0x04, 0x00010000 }, - { 0x418a90, 3, 0x04, 0x00000000 }, - { 0x418aa0, 3, 0x04, 0x00000000 }, - { 0x418aac, 1, 0x04, 0x00010000 }, - { 0x418ab0, 3, 0x04, 0x00000000 }, - { 0x418ac0, 3, 0x04, 0x00000000 }, - { 0x418acc, 1, 0x04, 0x00010000 }, - { 0x418ad0, 3, 0x04, 0x00000000 }, - { 0x418ae0, 3, 0x04, 0x00000000 }, - { 0x418aec, 1, 0x04, 0x00010000 }, - { 0x418af0, 3, 0x04, 0x00000000 }, - { 0x418b00, 1, 0x04, 0x00000000 }, - { 0x418b08, 1, 0x04, 0x0a418820 }, - { 0x418b0c, 1, 0x04, 0x062080e6 }, - { 0x418b10, 1, 0x04, 0x020398a4 }, - { 0x418b14, 1, 0x04, 0x0e629062 }, - { 0x418b18, 1, 0x04, 0x0a418820 }, - { 0x418b1c, 1, 0x04, 0x000000e6 }, - { 0x418bb8, 1, 0x04, 0x00000103 }, + {} +}; + +const struct nvc0_graph_init +nvc1_grctx_init_gpm_0[] = { { 0x418c08, 1, 0x04, 0x00000001 }, { 0x418c10, 8, 0x04, 0x00000000 }, { 0x418c6c, 1, 0x04, 0x00000001 }, { 0x418c80, 1, 0x04, 0x20200004 }, { 0x418c8c, 1, 0x04, 0x00000001 }, - { 0x419000, 1, 0x04, 0x00000780 }, - { 0x419004, 2, 0x04, 0x00000000 }, - { 0x419014, 1, 0x04, 0x00000004 }, {} }; -static struct nvc0_graph_init -nvc1_grctx_init_tpc[] = { +static const struct nvc0_graph_pack +nvc1_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvc0_grctx_init_prop_0 }, + { nvc0_grctx_init_gpc_unk_1 }, + { nvc1_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvc0_grctx_init_crstr_0 }, + { nvc1_grctx_init_gpm_0 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +const struct nvc0_graph_init +nvc1_grctx_init_pe_0[] = { { 0x419818, 1, 0x04, 0x00000000 }, { 0x41983c, 1, 0x04, 0x00038bc7 }, { 0x419848, 1, 0x04, 0x00000000 }, { 0x419864, 1, 0x04, 0x00000129 }, { 0x419888, 1, 0x04, 0x00000000 }, - { 0x419a00, 1, 0x04, 0x000001f0 }, - { 0x419a04, 1, 0x04, 0x00000001 }, - { 0x419a08, 1, 0x04, 0x00000023 }, - { 0x419a0c, 1, 0x04, 0x00020000 }, - { 0x419a10, 1, 0x04, 0x00000000 }, - { 0x419a14, 1, 0x04, 0x00000200 }, - { 0x419a1c, 1, 0x04, 0x00000000 }, - { 0x419a20, 1, 0x04, 0x00000800 }, - { 0x419ac4, 1, 0x04, 0x0007f440 }, + {} +}; + +const struct nvc0_graph_init +nvc1_grctx_init_wwdx_0[] = { { 0x419b00, 1, 0x04, 0x0a418820 }, { 0x419b04, 1, 0x04, 0x062080e6 }, { 0x419b08, 1, 0x04, 0x020398a4 }, @@ -701,28 +699,33 @@ nvc1_grctx_init_tpc[] = { { 0x419bd0, 1, 0x04, 0x00900103 }, { 0x419be0, 1, 0x04, 0x00400001 }, { 0x419be4, 1, 0x04, 0x00000000 }, - { 0x419c00, 1, 0x04, 0x00000002 }, - { 0x419c04, 1, 0x04, 0x00000006 }, - { 0x419c08, 1, 0x04, 0x00000002 }, - { 0x419c20, 1, 0x04, 0x00000000 }, - { 0x419cb0, 1, 0x04, 0x00020048 }, - { 0x419ce8, 1, 0x04, 0x00000000 }, - { 0x419cf4, 1, 0x04, 0x00000183 }, + {} +}; + +const struct nvc0_graph_init +nvc1_grctx_init_tpccs_0[] = { { 0x419d20, 1, 0x04, 0x12180000 }, { 0x419d24, 1, 0x04, 0x00001fff }, { 0x419d44, 1, 0x04, 0x02180218 }, - { 0x419e04, 3, 0x04, 0x00000000 }, - { 0x419e10, 1, 0x04, 0x00000002 }, - { 0x419e44, 1, 0x04, 0x001beff2 }, - { 0x419e48, 1, 0x04, 0x00000000 }, - { 0x419e4c, 1, 0x04, 0x0000000f }, - { 0x419e50, 17, 0x04, 0x00000000 }, - { 0x419e98, 1, 0x04, 0x00000000 }, - { 0x419ee0, 1, 0x04, 0x00011110 }, - { 0x419f30, 11, 0x04, 0x00000000 }, {} }; +static const struct nvc0_graph_pack +nvc1_grctx_pack_tpc[] = { + { nvc1_grctx_init_pe_0 }, + { nvc4_grctx_init_tex_0 }, + { nvc1_grctx_init_wwdx_0 }, + { nvc0_grctx_init_mpc_0 }, + { nvc4_grctx_init_l1c_0 }, + { nvc1_grctx_init_tpccs_0 }, + { nvc4_grctx_init_sm_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + void nvc1_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { @@ -771,41 +774,6 @@ nvc1_grctx_generate_unkn(struct nvc0_graph_priv *priv) nv_mask(priv, 0x419c00, 0x00000008, 0x00000008); } -static struct nvc0_graph_init * -nvc1_grctx_init_hub[] = { - nvc0_grctx_init_base, - nvc0_grctx_init_unk40xx, - nvc0_grctx_init_unk44xx, - nvc0_grctx_init_unk46xx, - nvc0_grctx_init_unk47xx, - nvc1_grctx_init_unk58xx, - nvc0_grctx_init_unk60xx, - nvc0_grctx_init_unk64xx, - nvc0_grctx_init_unk78xx, - nvc0_grctx_init_unk80xx, - nvc1_grctx_init_rop, - NULL -}; - -struct nvc0_graph_init * -nvc1_grctx_init_gpc[] = { - nvc1_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvc1_grctx_init_tpc, - NULL -}; - -static struct nvc0_graph_mthd -nvc1_grctx_init_mthd[] = { - { 0x9097, nvc1_grctx_init_9097, }, - { 0x9197, nvc1_grctx_init_9197, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x9039, nvc0_grctx_init_9039, }, - { 0x90c0, nvc0_grctx_init_90c0, }, - { 0x902d, nvc0_grctx_init_mthd_magic, }, - {} -}; - struct nouveau_oclass * nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xc1), @@ -817,11 +785,13 @@ nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nvc0_grctx_generate_main, - .mods = nvc1_grctx_generate_mods, - .unkn = nvc1_grctx_generate_unkn, - .hub = nvc1_grctx_init_hub, - .gpc = nvc1_grctx_init_gpc, - .icmd = nvc1_grctx_init_icmd, - .mthd = nvc1_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvc1_grctx_pack_tpc, + .icmd = nvc1_grctx_pack_icmd, + .mthd = nvc1_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c index 8f237b3bd8c..e11ed553819 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c @@ -22,15 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -static struct nvc0_graph_init -nvc3_grctx_init_tpc[] = { - { 0x419818, 1, 0x04, 0x00000000 }, - { 0x41983c, 1, 0x04, 0x00038bc7 }, - { 0x419848, 1, 0x04, 0x00000000 }, - { 0x419864, 1, 0x04, 0x0000012a }, - { 0x419888, 1, 0x04, 0x00000000 }, +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +const struct nvc0_graph_init +nvc4_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000001f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000023 }, @@ -40,24 +39,19 @@ nvc3_grctx_init_tpc[] = { { 0x419a1c, 1, 0x04, 0x00000000 }, { 0x419a20, 1, 0x04, 0x00000800 }, { 0x419ac4, 1, 0x04, 0x0007f440 }, - { 0x419b00, 1, 0x04, 0x0a418820 }, - { 0x419b04, 1, 0x04, 0x062080e6 }, - { 0x419b08, 1, 0x04, 0x020398a4 }, - { 0x419b0c, 1, 0x04, 0x0e629062 }, - { 0x419b10, 1, 0x04, 0x0a418820 }, - { 0x419b14, 1, 0x04, 0x000000e6 }, - { 0x419bd0, 1, 0x04, 0x00900103 }, - { 0x419be0, 1, 0x04, 0x00000001 }, - { 0x419be4, 1, 0x04, 0x00000000 }, - { 0x419c00, 1, 0x04, 0x00000002 }, - { 0x419c04, 1, 0x04, 0x00000006 }, - { 0x419c08, 1, 0x04, 0x00000002 }, - { 0x419c20, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc4_grctx_init_l1c_0[] = { { 0x419cb0, 1, 0x04, 0x00020048 }, { 0x419ce8, 1, 0x04, 0x00000000 }, { 0x419cf4, 1, 0x04, 0x00000183 }, - { 0x419d20, 1, 0x04, 0x02180000 }, - { 0x419d24, 1, 0x04, 0x00001fff }, + {} +}; + +const struct nvc0_graph_init +nvc4_grctx_init_sm_0[] = { { 0x419e04, 3, 0x04, 0x00000000 }, { 0x419e10, 1, 0x04, 0x00000002 }, { 0x419e44, 1, 0x04, 0x001beff2 }, @@ -70,16 +64,24 @@ nvc3_grctx_init_tpc[] = { {} }; -struct nvc0_graph_init * -nvc3_grctx_init_gpc[] = { - nvc0_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvc3_grctx_init_tpc, - NULL +static const struct nvc0_graph_pack +nvc4_grctx_pack_tpc[] = { + { nvc0_grctx_init_pe_0 }, + { nvc4_grctx_init_tex_0 }, + { nvc0_grctx_init_wwdx_0 }, + { nvc0_grctx_init_mpc_0 }, + { nvc4_grctx_init_l1c_0 }, + { nvc0_grctx_init_tpccs_0 }, + { nvc4_grctx_init_sm_0 }, + {} }; +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + struct nouveau_oclass * -nvc3_grctx_oclass = &(struct nvc0_grctx_oclass) { +nvc4_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xc3), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nvc0_graph_context_ctor, @@ -89,11 +91,13 @@ nvc3_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nvc0_grctx_generate_main, - .mods = nvc0_grctx_generate_mods, - .unkn = nvc0_grctx_generate_unkn, - .hub = nvc0_grctx_init_hub, - .gpc = nvc3_grctx_init_gpc, - .icmd = nvc0_grctx_init_icmd, - .mthd = nvc0_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvc4_grctx_pack_tpc, + .icmd = nvc0_grctx_pack_icmd, + .mthd = nvc0_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c index d0d4ce3c489..feebd58dfe8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c @@ -22,10 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -static struct nvc0_graph_init -nvc8_grctx_init_icmd[] = { +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nvc8_grctx_init_icmd_0[] = { { 0x001000, 1, 0x01, 0x00000004 }, { 0x0000a9, 1, 0x01, 0x0000ffff }, { 0x000038, 1, 0x01, 0x0fac6881 }, @@ -141,8 +145,7 @@ nvc8_grctx_init_icmd[] = { { 0x000586, 1, 0x01, 0x00000040 }, { 0x000582, 2, 0x01, 0x00000080 }, { 0x0005c2, 1, 0x01, 0x00000001 }, - { 0x000638, 1, 0x01, 0x00000001 }, - { 0x000639, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, { 0x00063a, 1, 0x01, 0x00000002 }, { 0x00063b, 2, 0x01, 0x00000001 }, { 0x00063d, 1, 0x01, 0x00000002 }, @@ -203,15 +206,13 @@ nvc8_grctx_init_icmd[] = { { 0x000787, 1, 0x01, 0x000000cf }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x000836, 1, 0x01, 0x00000001 }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x00080c, 1, 0x01, 0x00000002 }, { 0x00080d, 2, 0x01, 0x00000100 }, @@ -237,14 +238,12 @@ nvc8_grctx_init_icmd[] = { { 0x0006b1, 1, 0x01, 0x00000011 }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x01e100, 1, 0x01, 0x00000001 }, { 0x001000, 1, 0x01, 0x00000014 }, @@ -269,58 +268,20 @@ nvc8_grctx_init_icmd[] = { {} }; -static struct nvc0_graph_init -nvc8_grctx_init_tpc[] = { - { 0x419818, 1, 0x04, 0x00000000 }, - { 0x41983c, 1, 0x04, 0x00038bc7 }, - { 0x419848, 1, 0x04, 0x00000000 }, - { 0x419864, 1, 0x04, 0x0000012a }, - { 0x419888, 1, 0x04, 0x00000000 }, - { 0x419a00, 1, 0x04, 0x000001f0 }, - { 0x419a04, 1, 0x04, 0x00000001 }, - { 0x419a08, 1, 0x04, 0x00000023 }, - { 0x419a0c, 1, 0x04, 0x00020000 }, - { 0x419a10, 1, 0x04, 0x00000000 }, - { 0x419a14, 1, 0x04, 0x00000200 }, - { 0x419a1c, 1, 0x04, 0x00000000 }, - { 0x419a20, 1, 0x04, 0x00000800 }, - { 0x419b00, 1, 0x04, 0x0a418820 }, - { 0x419b04, 1, 0x04, 0x062080e6 }, - { 0x419b08, 1, 0x04, 0x020398a4 }, - { 0x419b0c, 1, 0x04, 0x0e629062 }, - { 0x419b10, 1, 0x04, 0x0a418820 }, - { 0x419b14, 1, 0x04, 0x000000e6 }, - { 0x419bd0, 1, 0x04, 0x00900103 }, - { 0x419be0, 1, 0x04, 0x00000001 }, - { 0x419be4, 1, 0x04, 0x00000000 }, - { 0x419c00, 1, 0x04, 0x00000002 }, - { 0x419c04, 1, 0x04, 0x00000006 }, - { 0x419c08, 1, 0x04, 0x00000002 }, - { 0x419c20, 1, 0x04, 0x00000000 }, - { 0x419cb0, 1, 0x04, 0x00060048 }, - { 0x419ce8, 1, 0x04, 0x00000000 }, - { 0x419cf4, 1, 0x04, 0x00000183 }, - { 0x419d20, 1, 0x04, 0x02180000 }, - { 0x419d24, 1, 0x04, 0x00001fff }, - { 0x419e04, 3, 0x04, 0x00000000 }, - { 0x419e10, 1, 0x04, 0x00000002 }, - { 0x419e44, 1, 0x04, 0x001beff2 }, - { 0x419e48, 1, 0x04, 0x00000000 }, - { 0x419e4c, 1, 0x04, 0x0000000f }, - { 0x419e50, 17, 0x04, 0x00000000 }, - { 0x419e98, 1, 0x04, 0x00000000 }, - { 0x419f50, 2, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nvc8_grctx_pack_icmd[] = { + { nvc8_grctx_init_icmd_0 }, {} }; -struct nvc0_graph_init -nvc8_grctx_init_9197[] = { +const struct nvc0_graph_init +nvc8_grctx_init_9197_0[] = { { 0x0002e4, 1, 0x04, 0x0000b001 }, {} }; -struct nvc0_graph_init -nvc8_grctx_init_9297[] = { +const struct nvc0_graph_init +nvc8_grctx_init_9297_0[] = { { 0x003400, 128, 0x04, 0x00000000 }, { 0x00036c, 2, 0x04, 0x00000000 }, { 0x0007a4, 2, 0x04, 0x00000000 }, @@ -329,26 +290,47 @@ nvc8_grctx_init_9297[] = { {} }; -static struct nvc0_graph_mthd -nvc8_grctx_init_mthd[] = { - { 0x9097, nvc1_grctx_init_9097, }, - { 0x9197, nvc8_grctx_init_9197, }, - { 0x9297, nvc8_grctx_init_9297, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x9039, nvc0_grctx_init_9039, }, - { 0x90c0, nvc0_grctx_init_90c0, }, - { 0x902d, nvc0_grctx_init_mthd_magic, }, +static const struct nvc0_graph_pack +nvc8_grctx_pack_mthd[] = { + { nvc1_grctx_init_9097_0, 0x9097 }, + { nvc8_grctx_init_9197_0, 0x9197 }, + { nvc8_grctx_init_9297_0, 0x9297 }, + { nvc0_grctx_init_902d_0, 0x902d }, + { nvc0_grctx_init_9039_0, 0x9039 }, + { nvc0_grctx_init_90c0_0, 0x90c0 }, + {} +}; + +static const struct nvc0_graph_init +nvc8_grctx_init_setup_0[] = { + { 0x418800, 1, 0x04, 0x0006860a }, + { 0x418808, 3, 0x04, 0x00000000 }, + { 0x418828, 1, 0x04, 0x00008442 }, + { 0x418830, 1, 0x04, 0x00000001 }, + { 0x4188d8, 1, 0x04, 0x00000008 }, + { 0x4188e0, 1, 0x04, 0x01000000 }, + { 0x4188e8, 5, 0x04, 0x00000000 }, + { 0x4188fc, 1, 0x04, 0x20100000 }, {} }; -static struct nvc0_graph_init * -nvc8_grctx_init_gpc[] = { - nvc0_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvc8_grctx_init_tpc, - NULL +static const struct nvc0_graph_pack +nvc8_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvc0_grctx_init_prop_0 }, + { nvc0_grctx_init_gpc_unk_1 }, + { nvc8_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvc0_grctx_init_crstr_0 }, + { nvc0_grctx_init_gpm_0 }, + { nvc0_grctx_init_gcc_0 }, + {} }; +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + struct nouveau_oclass * nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xc8), @@ -360,11 +342,13 @@ nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nvc0_grctx_generate_main, - .mods = nvc0_grctx_generate_mods, - .unkn = nvc0_grctx_generate_unkn, - .hub = nvc0_grctx_init_hub, - .gpc = nvc8_grctx_init_gpc, - .icmd = nvc8_grctx_init_icmd, - .mthd = nvc8_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvc0_grctx_pack_tpc, + .icmd = nvc8_grctx_pack_icmd, + .mthd = nvc8_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c index c4740d52853..1dbc8d7f2e8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c @@ -22,33 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -struct nvc0_graph_init -nvd7_grctx_init_unk40xx[] = { - { 0x404004, 10, 0x04, 0x00000000 }, - { 0x404044, 1, 0x04, 0x00000000 }, - { 0x404094, 1, 0x04, 0x00000000 }, - { 0x404098, 12, 0x04, 0x00000000 }, - { 0x4040c8, 1, 0x04, 0xf0000087 }, - { 0x4040d0, 6, 0x04, 0x00000000 }, - { 0x4040e8, 1, 0x04, 0x00001000 }, - { 0x4040f8, 1, 0x04, 0x00000000 }, - { 0x404130, 1, 0x04, 0x00000000 }, - { 0x404134, 1, 0x04, 0x00000000 }, - { 0x404138, 1, 0x04, 0x20000040 }, - { 0x404150, 1, 0x04, 0x0000002e }, - { 0x404154, 1, 0x04, 0x00000400 }, - { 0x404158, 1, 0x04, 0x00000200 }, - { 0x404164, 1, 0x04, 0x00000055 }, - { 0x404168, 1, 0x04, 0x00000000 }, - { 0x404178, 2, 0x04, 0x00000000 }, - { 0x404200, 8, 0x04, 0x00000000 }, - {} -}; +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ -static struct nvc0_graph_init -nvd7_grctx_init_unk58xx[] = { +static const struct nvc0_graph_init +nvd7_grctx_init_ds_0[] = { { 0x405800, 1, 0x04, 0x0f8000bf }, { 0x405830, 1, 0x04, 0x02180324 }, { 0x405834, 1, 0x04, 0x08000000 }, @@ -60,8 +41,10 @@ nvd7_grctx_init_unk58xx[] = { {} }; -static struct nvc0_graph_init -nvd7_grctx_init_unk64xx[] = { +static const struct nvc0_graph_init +nvd7_grctx_init_pd_0[] = { + { 0x406020, 1, 0x04, 0x000103c1 }, + { 0x406028, 4, 0x04, 0x00000001 }, { 0x4064a8, 1, 0x04, 0x00000000 }, { 0x4064ac, 1, 0x04, 0x00003fff }, { 0x4064b4, 3, 0x04, 0x00000000 }, @@ -71,22 +54,22 @@ nvd7_grctx_init_unk64xx[] = { {} }; -static struct nvc0_graph_init -nvd7_grctx_init_gpc_0[] = { - { 0x418380, 1, 0x04, 0x00000016 }, - { 0x418400, 1, 0x04, 0x38004e00 }, - { 0x418404, 1, 0x04, 0x71e0ffff }, - { 0x41840c, 1, 0x04, 0x00001008 }, - { 0x418410, 1, 0x04, 0x0fff0fff }, - { 0x418414, 1, 0x04, 0x02200fff }, - { 0x418450, 6, 0x04, 0x00000000 }, - { 0x418468, 1, 0x04, 0x00000001 }, - { 0x41846c, 2, 0x04, 0x00000000 }, - { 0x418600, 1, 0x04, 0x0000001f }, - { 0x418684, 1, 0x04, 0x0000000f }, - { 0x418700, 1, 0x04, 0x00000002 }, - { 0x418704, 1, 0x04, 0x00000080 }, - { 0x418708, 3, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nvd7_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nvd9_grctx_init_fe_0 }, + { nvc0_grctx_init_pri_0 }, + { nvc0_grctx_init_memfmt_0 }, + { nvd7_grctx_init_ds_0 }, + { nvd7_grctx_init_pd_0 }, + { nvc0_grctx_init_rstr2d_0 }, + { nvc0_grctx_init_scc_0 }, + { nvd9_grctx_init_be_0 }, + {} +}; + +static const struct nvc0_graph_init +nvd7_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x7006860a }, { 0x418808, 3, 0x04, 0x00000000 }, { 0x418828, 1, 0x04, 0x00008442 }, @@ -95,34 +78,32 @@ nvd7_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x20100018 }, - { 0x41891c, 1, 0x04, 0x00ff00ff }, - { 0x418924, 1, 0x04, 0x00000000 }, - { 0x418928, 1, 0x04, 0x00ffff00 }, - { 0x41892c, 1, 0x04, 0x0000ff00 }, - { 0x418b00, 1, 0x04, 0x00000006 }, - { 0x418b08, 1, 0x04, 0x0a418820 }, - { 0x418b0c, 1, 0x04, 0x062080e6 }, - { 0x418b10, 1, 0x04, 0x020398a4 }, - { 0x418b14, 1, 0x04, 0x0e629062 }, - { 0x418b18, 1, 0x04, 0x0a418820 }, - { 0x418b1c, 1, 0x04, 0x000000e6 }, - { 0x418bb8, 1, 0x04, 0x00000103 }, - { 0x418c08, 1, 0x04, 0x00000001 }, - { 0x418c10, 8, 0x04, 0x00000000 }, - { 0x418c6c, 1, 0x04, 0x00000001 }, - { 0x418c80, 1, 0x04, 0x20200004 }, - { 0x418c8c, 1, 0x04, 0x00000001 }, - { 0x419000, 1, 0x04, 0x00000780 }, - { 0x419004, 2, 0x04, 0x00000000 }, - { 0x419014, 1, 0x04, 0x00000004 }, {} }; -static struct nvc0_graph_init -nvd7_grctx_init_tpc[] = { +static const struct nvc0_graph_pack +nvd7_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvd9_grctx_init_prop_0 }, + { nvd9_grctx_init_gpc_unk_1 }, + { nvd7_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvd9_grctx_init_crstr_0 }, + { nvc1_grctx_init_gpm_0 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +const struct nvc0_graph_init +nvd7_grctx_init_pe_0[] = { { 0x419848, 1, 0x04, 0x00000000 }, { 0x419864, 1, 0x04, 0x00000129 }, { 0x419888, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvd7_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000001f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000023 }, @@ -132,33 +113,46 @@ nvd7_grctx_init_tpc[] = { { 0x419a1c, 1, 0x04, 0x00008000 }, { 0x419a20, 1, 0x04, 0x00000800 }, { 0x419ac4, 1, 0x04, 0x0017f440 }, + {} +}; + +static const struct nvc0_graph_init +nvd7_grctx_init_mpc_0[] = { { 0x419c00, 1, 0x04, 0x0000000a }, { 0x419c04, 1, 0x04, 0x00000006 }, { 0x419c08, 1, 0x04, 0x00000002 }, { 0x419c20, 1, 0x04, 0x00000000 }, { 0x419c24, 1, 0x04, 0x00084210 }, { 0x419c28, 1, 0x04, 0x3efbefbe }, - { 0x419cb0, 1, 0x04, 0x00020048 }, - { 0x419ce8, 1, 0x04, 0x00000000 }, - { 0x419cf4, 1, 0x04, 0x00000183 }, - { 0x419e04, 3, 0x04, 0x00000000 }, - { 0x419e10, 1, 0x04, 0x00000002 }, - { 0x419e44, 1, 0x04, 0x001beff2 }, - { 0x419e48, 1, 0x04, 0x00000000 }, - { 0x419e4c, 1, 0x04, 0x0000000f }, - { 0x419e50, 17, 0x04, 0x00000000 }, - { 0x419e98, 1, 0x04, 0x00000000 }, - { 0x419ee0, 1, 0x04, 0x00010110 }, - { 0x419f30, 11, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvd7_grctx_init_unk[] = { +static const struct nvc0_graph_pack +nvd7_grctx_pack_tpc[] = { + { nvd7_grctx_init_pe_0 }, + { nvd7_grctx_init_tex_0 }, + { nvd7_grctx_init_mpc_0 }, + { nvc4_grctx_init_l1c_0 }, + { nvd9_grctx_init_sm_0 }, + {} +}; + +static const struct nvc0_graph_init +nvd7_grctx_init_pes_0[] = { { 0x41be24, 1, 0x04, 0x00000002 }, + {} +}; + +static const struct nvc0_graph_init +nvd7_grctx_init_cbm_0[] = { { 0x41bec0, 1, 0x04, 0x12180000 }, { 0x41bec4, 1, 0x04, 0x00003fff }, { 0x41bee4, 1, 0x04, 0x03240218 }, + {} +}; + +const struct nvc0_graph_init +nvd7_grctx_init_wwdx_0[] = { { 0x41bf00, 1, 0x04, 0x0a418820 }, { 0x41bf04, 1, 0x04, 0x062080e6 }, { 0x41bf08, 1, 0x04, 0x020398a4 }, @@ -171,6 +165,18 @@ nvd7_grctx_init_unk[] = { {} }; +static const struct nvc0_graph_pack +nvd7_grctx_pack_ppc[] = { + { nvd7_grctx_init_pes_0 }, + { nvd7_grctx_init_cbm_0 }, + { nvd7_grctx_init_wwdx_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + static void nvd7_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { @@ -219,10 +225,11 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_mask(priv, 0x000260, 0x00000001, 0x00000000); - for (i = 0; oclass->hub[i]; i++) - nvc0_graph_mmio(priv, oclass->hub[i]); - for (i = 0; oclass->gpc[i]; i++) - nvc0_graph_mmio(priv, oclass->gpc[i]); + nvc0_graph_mmio(priv, oclass->hub); + nvc0_graph_mmio(priv, oclass->gpc); + nvc0_graph_mmio(priv, oclass->zcull); + nvc0_graph_mmio(priv, oclass->tpc); + nvc0_graph_mmio(priv, oclass->ppc); nv_wr32(priv, 0x404154, 0x00000000); @@ -244,32 +251,6 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_mask(priv, 0x000260, 0x00000001, 0x00000001); } - -static struct nvc0_graph_init * -nvd7_grctx_init_hub[] = { - nvc0_grctx_init_base, - nvd7_grctx_init_unk40xx, - nvc0_grctx_init_unk44xx, - nvc0_grctx_init_unk46xx, - nvc0_grctx_init_unk47xx, - nvd7_grctx_init_unk58xx, - nvc0_grctx_init_unk60xx, - nvd7_grctx_init_unk64xx, - nvc0_grctx_init_unk78xx, - nvc0_grctx_init_unk80xx, - nvd9_grctx_init_rop, - NULL -}; - -struct nvc0_graph_init * -nvd7_grctx_init_gpc[] = { - nvd7_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvd7_grctx_init_tpc, - nvd7_grctx_init_unk, - NULL -}; - struct nouveau_oclass * nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xd7), @@ -281,11 +262,14 @@ nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nvd7_grctx_generate_main, - .mods = nvd7_grctx_generate_mods, - .unkn = nve4_grctx_generate_unkn, - .hub = nvd7_grctx_init_hub, - .gpc = nvd7_grctx_init_gpc, - .icmd = nvd9_grctx_init_icmd, - .mthd = nvd9_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvd7_grctx_pack_tpc, + .ppc = nvd7_grctx_pack_ppc, + .icmd = nvd9_grctx_pack_icmd, + .mthd = nvd9_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c index a1102cbf2fd..c665fb7e466 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c @@ -22,38 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -struct nvc0_graph_init -nvd9_grctx_init_90c0[] = { - { 0x002700, 4, 0x40, 0x00000000 }, - { 0x002720, 4, 0x40, 0x00000000 }, - { 0x002704, 4, 0x40, 0x00000000 }, - { 0x002724, 4, 0x40, 0x00000000 }, - { 0x002708, 4, 0x40, 0x00000000 }, - { 0x002728, 4, 0x40, 0x00000000 }, - { 0x00270c, 8, 0x20, 0x00000000 }, - { 0x002710, 4, 0x40, 0x00014000 }, - { 0x002730, 4, 0x40, 0x00014000 }, - { 0x002714, 4, 0x40, 0x00000040 }, - { 0x002734, 4, 0x40, 0x00000040 }, - { 0x00030c, 1, 0x04, 0x00000001 }, - { 0x001944, 1, 0x04, 0x00000000 }, - { 0x000758, 1, 0x04, 0x00000100 }, - { 0x0002c4, 1, 0x04, 0x00000000 }, - { 0x000790, 5, 0x04, 0x00000000 }, - { 0x00077c, 1, 0x04, 0x00000000 }, - { 0x000204, 3, 0x04, 0x00000000 }, - { 0x000214, 1, 0x04, 0x00000000 }, - { 0x00024c, 1, 0x04, 0x00000000 }, - { 0x000d94, 1, 0x04, 0x00000001 }, - { 0x001608, 2, 0x04, 0x00000000 }, - { 0x001664, 1, 0x04, 0x00000000 }, - {} -}; +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ -struct nvc0_graph_init -nvd9_grctx_init_icmd[] = { +static const struct nvc0_graph_init +nvd9_grctx_init_icmd_0[] = { { 0x001000, 1, 0x01, 0x00000004 }, { 0x0000a9, 1, 0x01, 0x0000ffff }, { 0x000038, 1, 0x01, 0x0fac6881 }, @@ -171,8 +147,7 @@ nvd9_grctx_init_icmd[] = { { 0x000586, 1, 0x01, 0x00000040 }, { 0x000582, 2, 0x01, 0x00000080 }, { 0x0005c2, 1, 0x01, 0x00000001 }, - { 0x000638, 1, 0x01, 0x00000001 }, - { 0x000639, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, { 0x00063a, 1, 0x01, 0x00000002 }, { 0x00063b, 2, 0x01, 0x00000001 }, { 0x00063d, 1, 0x01, 0x00000002 }, @@ -233,15 +208,13 @@ nvd9_grctx_init_icmd[] = { { 0x000787, 1, 0x01, 0x000000cf }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x000836, 1, 0x01, 0x00000001 }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x00080c, 1, 0x01, 0x00000002 }, { 0x00080d, 2, 0x01, 0x00000100 }, @@ -267,14 +240,12 @@ nvd9_grctx_init_icmd[] = { { 0x0006b1, 1, 0x01, 0x00000011 }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x01e100, 1, 0x01, 0x00000001 }, { 0x001000, 1, 0x01, 0x00000014 }, @@ -299,18 +270,56 @@ nvd9_grctx_init_icmd[] = { {} }; -struct nvc0_graph_init -nvd9_grctx_init_unk40xx[] = { - { 0x404004, 11, 0x04, 0x00000000 }, +const struct nvc0_graph_pack +nvd9_grctx_pack_icmd[] = { + { nvd9_grctx_init_icmd_0 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_grctx_init_90c0_0[] = { + { 0x002700, 8, 0x20, 0x00000000 }, + { 0x002704, 8, 0x20, 0x00000000 }, + { 0x002708, 8, 0x20, 0x00000000 }, + { 0x00270c, 8, 0x20, 0x00000000 }, + { 0x002710, 8, 0x20, 0x00014000 }, + { 0x002714, 8, 0x20, 0x00000040 }, + { 0x00030c, 1, 0x04, 0x00000001 }, + { 0x001944, 1, 0x04, 0x00000000 }, + { 0x000758, 1, 0x04, 0x00000100 }, + { 0x0002c4, 1, 0x04, 0x00000000 }, + { 0x000790, 5, 0x04, 0x00000000 }, + { 0x00077c, 1, 0x04, 0x00000000 }, + { 0x000204, 3, 0x04, 0x00000000 }, + { 0x000214, 1, 0x04, 0x00000000 }, + { 0x00024c, 1, 0x04, 0x00000000 }, + { 0x000d94, 1, 0x04, 0x00000001 }, + { 0x001608, 2, 0x04, 0x00000000 }, + { 0x001664, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_pack +nvd9_grctx_pack_mthd[] = { + { nvc1_grctx_init_9097_0, 0x9097 }, + { nvc8_grctx_init_9197_0, 0x9197 }, + { nvc8_grctx_init_9297_0, 0x9297 }, + { nvc0_grctx_init_902d_0, 0x902d }, + { nvc0_grctx_init_9039_0, 0x9039 }, + { nvd9_grctx_init_90c0_0, 0x90c0 }, + {} +}; + +const struct nvc0_graph_init +nvd9_grctx_init_fe_0[] = { + { 0x404004, 10, 0x04, 0x00000000 }, { 0x404044, 1, 0x04, 0x00000000 }, - { 0x404094, 1, 0x04, 0x00000000 }, - { 0x404098, 12, 0x04, 0x00000000 }, + { 0x404094, 13, 0x04, 0x00000000 }, { 0x4040c8, 1, 0x04, 0xf0000087 }, { 0x4040d0, 6, 0x04, 0x00000000 }, { 0x4040e8, 1, 0x04, 0x00001000 }, { 0x4040f8, 1, 0x04, 0x00000000 }, - { 0x404130, 1, 0x04, 0x00000000 }, - { 0x404134, 1, 0x04, 0x00000000 }, + { 0x404130, 2, 0x04, 0x00000000 }, { 0x404138, 1, 0x04, 0x20000040 }, { 0x404150, 1, 0x04, 0x0000002e }, { 0x404154, 1, 0x04, 0x00000400 }, @@ -322,8 +331,8 @@ nvd9_grctx_init_unk40xx[] = { {} }; -static struct nvc0_graph_init -nvd9_grctx_init_unk58xx[] = { +static const struct nvc0_graph_init +nvd9_grctx_init_ds_0[] = { { 0x405800, 1, 0x04, 0x0f8000bf }, { 0x405830, 1, 0x04, 0x02180218 }, { 0x405834, 1, 0x04, 0x08000000 }, @@ -335,8 +344,10 @@ nvd9_grctx_init_unk58xx[] = { {} }; -static struct nvc0_graph_init -nvd9_grctx_init_unk64xx[] = { +static const struct nvc0_graph_init +nvd9_grctx_init_pd_0[] = { + { 0x406020, 1, 0x04, 0x000103c1 }, + { 0x406028, 4, 0x04, 0x00000001 }, { 0x4064a8, 1, 0x04, 0x00000000 }, { 0x4064ac, 1, 0x04, 0x00003fff }, { 0x4064b4, 3, 0x04, 0x00000000 }, @@ -345,21 +356,34 @@ nvd9_grctx_init_unk64xx[] = { {} }; -struct nvc0_graph_init -nvd9_grctx_init_rop[] = { +const struct nvc0_graph_init +nvd9_grctx_init_be_0[] = { { 0x408800, 1, 0x04, 0x02802a3c }, { 0x408804, 1, 0x04, 0x00000040 }, { 0x408808, 1, 0x04, 0x1043e005 }, { 0x408900, 1, 0x04, 0x3080b801 }, - { 0x408904, 1, 0x04, 0x1043e005 }, + { 0x408904, 1, 0x04, 0x62000001 }, { 0x408908, 1, 0x04, 0x00c8102f }, { 0x408980, 1, 0x04, 0x0000011d }, {} }; -static struct nvc0_graph_init -nvd9_grctx_init_gpc_0[] = { - { 0x418380, 1, 0x04, 0x00000016 }, +static const struct nvc0_graph_pack +nvd9_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nvd9_grctx_init_fe_0 }, + { nvc0_grctx_init_pri_0 }, + { nvc0_grctx_init_memfmt_0 }, + { nvd9_grctx_init_ds_0 }, + { nvd9_grctx_init_pd_0 }, + { nvc0_grctx_init_rstr2d_0 }, + { nvc0_grctx_init_scc_0 }, + { nvd9_grctx_init_be_0 }, + {} +}; + +const struct nvc0_graph_init +nvd9_grctx_init_prop_0[] = { { 0x418400, 1, 0x04, 0x38004e00 }, { 0x418404, 1, 0x04, 0x71e0ffff }, { 0x41840c, 1, 0x04, 0x00001008 }, @@ -368,11 +392,21 @@ nvd9_grctx_init_gpc_0[] = { { 0x418450, 6, 0x04, 0x00000000 }, { 0x418468, 1, 0x04, 0x00000001 }, { 0x41846c, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd9_grctx_init_gpc_unk_1[] = { { 0x418600, 1, 0x04, 0x0000001f }, { 0x418684, 1, 0x04, 0x0000000f }, { 0x418700, 1, 0x04, 0x00000002 }, { 0x418704, 1, 0x04, 0x00000080 }, { 0x418708, 3, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x7006860a }, { 0x418808, 3, 0x04, 0x00000000 }, { 0x418828, 1, 0x04, 0x00008442 }, @@ -381,10 +415,11 @@ nvd9_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x20100008 }, - { 0x41891c, 1, 0x04, 0x00ff00ff }, - { 0x418924, 1, 0x04, 0x00000000 }, - { 0x418928, 1, 0x04, 0x00ffff00 }, - { 0x41892c, 1, 0x04, 0x0000ff00 }, + {} +}; + +const struct nvc0_graph_init +nvd9_grctx_init_crstr_0[] = { { 0x418b00, 1, 0x04, 0x00000006 }, { 0x418b08, 1, 0x04, 0x0a418820 }, { 0x418b0c, 1, 0x04, 0x062080e6 }, @@ -393,24 +428,24 @@ nvd9_grctx_init_gpc_0[] = { { 0x418b18, 1, 0x04, 0x0a418820 }, { 0x418b1c, 1, 0x04, 0x000000e6 }, { 0x418bb8, 1, 0x04, 0x00000103 }, - { 0x418c08, 1, 0x04, 0x00000001 }, - { 0x418c10, 8, 0x04, 0x00000000 }, - { 0x418c6c, 1, 0x04, 0x00000001 }, - { 0x418c80, 1, 0x04, 0x20200004 }, - { 0x418c8c, 1, 0x04, 0x00000001 }, - { 0x419000, 1, 0x04, 0x00000780 }, - { 0x419004, 2, 0x04, 0x00000000 }, - { 0x419014, 1, 0x04, 0x00000004 }, {} }; -static struct nvc0_graph_init -nvd9_grctx_init_tpc[] = { - { 0x419818, 1, 0x04, 0x00000000 }, - { 0x41983c, 1, 0x04, 0x00038bc7 }, - { 0x419848, 1, 0x04, 0x00000000 }, - { 0x419864, 1, 0x04, 0x00000129 }, - { 0x419888, 1, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nvd9_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvd9_grctx_init_prop_0 }, + { nvd9_grctx_init_gpc_unk_1 }, + { nvd9_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvd9_grctx_init_crstr_0 }, + { nvc1_grctx_init_gpm_0 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000001f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000023 }, @@ -420,27 +455,22 @@ nvd9_grctx_init_tpc[] = { { 0x419a1c, 1, 0x04, 0x00000000 }, { 0x419a20, 1, 0x04, 0x00000800 }, { 0x419ac4, 1, 0x04, 0x0017f440 }, - { 0x419b00, 1, 0x04, 0x0a418820 }, - { 0x419b04, 1, 0x04, 0x062080e6 }, - { 0x419b08, 1, 0x04, 0x020398a4 }, - { 0x419b0c, 1, 0x04, 0x0e629062 }, - { 0x419b10, 1, 0x04, 0x0a418820 }, - { 0x419b14, 1, 0x04, 0x000000e6 }, - { 0x419bd0, 1, 0x04, 0x00900103 }, - { 0x419be0, 1, 0x04, 0x00400001 }, - { 0x419be4, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_grctx_init_mpc_0[] = { { 0x419c00, 1, 0x04, 0x0000000a }, { 0x419c04, 1, 0x04, 0x00000006 }, { 0x419c08, 1, 0x04, 0x00000002 }, { 0x419c20, 1, 0x04, 0x00000000 }, { 0x419c24, 1, 0x04, 0x00084210 }, { 0x419c28, 1, 0x04, 0x3cf3cf3c }, - { 0x419cb0, 1, 0x04, 0x00020048 }, - { 0x419ce8, 1, 0x04, 0x00000000 }, - { 0x419cf4, 1, 0x04, 0x00000183 }, - { 0x419d20, 1, 0x04, 0x12180000 }, - { 0x419d24, 1, 0x04, 0x00001fff }, - { 0x419d44, 1, 0x04, 0x02180218 }, + {} +}; + +const struct nvc0_graph_init +nvd9_grctx_init_sm_0[] = { { 0x419e04, 3, 0x04, 0x00000000 }, { 0x419e10, 1, 0x04, 0x00000002 }, { 0x419e44, 1, 0x04, 0x001beff2 }, @@ -453,47 +483,21 @@ nvd9_grctx_init_tpc[] = { {} }; -static struct nvc0_graph_init * -nvd9_grctx_init_hub[] = { - nvc0_grctx_init_base, - nvd9_grctx_init_unk40xx, - nvc0_grctx_init_unk44xx, - nvc0_grctx_init_unk46xx, - nvc0_grctx_init_unk47xx, - nvd9_grctx_init_unk58xx, - nvc0_grctx_init_unk60xx, - nvd9_grctx_init_unk64xx, - nvc0_grctx_init_unk78xx, - nvc0_grctx_init_unk80xx, - nvd9_grctx_init_rop, - NULL -}; - -struct nvc0_graph_init * -nvd9_grctx_init_gpc[] = { - nvd9_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvd9_grctx_init_tpc, - NULL -}; - -struct nvc0_graph_init -nvd9_grctx_init_mthd_magic[] = { - { 0x3410, 1, 0x04, 0x80002006 }, +static const struct nvc0_graph_pack +nvd9_grctx_pack_tpc[] = { + { nvc1_grctx_init_pe_0 }, + { nvd9_grctx_init_tex_0 }, + { nvc1_grctx_init_wwdx_0 }, + { nvd9_grctx_init_mpc_0 }, + { nvc4_grctx_init_l1c_0 }, + { nvc1_grctx_init_tpccs_0 }, + { nvd9_grctx_init_sm_0 }, {} }; -struct nvc0_graph_mthd -nvd9_grctx_init_mthd[] = { - { 0x9097, nvc1_grctx_init_9097, }, - { 0x9197, nvc8_grctx_init_9197, }, - { 0x9297, nvc8_grctx_init_9297, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x9039, nvc0_grctx_init_9039, }, - { 0x90c0, nvd9_grctx_init_90c0, }, - { 0x902d, nvd9_grctx_init_mthd_magic, }, - {} -}; +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ struct nouveau_oclass * nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) { @@ -506,11 +510,13 @@ nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nvc0_grctx_generate_main, - .mods = nvc1_grctx_generate_mods, - .unkn = nvc1_grctx_generate_unkn, - .hub = nvd9_grctx_init_hub, - .gpc = nvd9_grctx_init_gpc, - .icmd = nvd9_grctx_init_icmd, - .mthd = nvd9_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvd9_grctx_pack_tpc, + .icmd = nvd9_grctx_pack_icmd, + .mthd = nvd9_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c index e2de73ee5ee..c5b24923858 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c @@ -22,10 +22,14 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -struct nvc0_graph_init -nve4_grctx_init_icmd[] = { +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nve4_grctx_init_icmd_0[] = { { 0x001000, 1, 0x01, 0x00000004 }, { 0x000039, 3, 0x01, 0x00000000 }, { 0x0000a9, 1, 0x01, 0x0000ffff }, @@ -138,8 +142,7 @@ nve4_grctx_init_icmd[] = { { 0x000586, 1, 0x01, 0x00000040 }, { 0x000582, 2, 0x01, 0x00000080 }, { 0x0005c2, 1, 0x01, 0x00000001 }, - { 0x000638, 1, 0x01, 0x00000001 }, - { 0x000639, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, { 0x00063a, 1, 0x01, 0x00000002 }, { 0x00063b, 2, 0x01, 0x00000001 }, { 0x00063d, 1, 0x01, 0x00000002 }, @@ -197,15 +200,13 @@ nve4_grctx_init_icmd[] = { { 0x000787, 1, 0x01, 0x000000cf }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x000836, 1, 0x01, 0x00000001 }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x000b07, 1, 0x01, 0x00000002 }, { 0x000b08, 2, 0x01, 0x00000100 }, @@ -231,14 +232,12 @@ nve4_grctx_init_icmd[] = { { 0x0006b1, 1, 0x01, 0x00000011 }, { 0x00078c, 1, 0x01, 0x00000008 }, { 0x000792, 1, 0x01, 0x00000001 }, - { 0x000794, 1, 0x01, 0x00000001 }, - { 0x000795, 2, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, { 0x000797, 1, 0x01, 0x000000cf }, { 0x00079a, 1, 0x01, 0x00000002 }, { 0x000833, 1, 0x01, 0x04444480 }, { 0x0007a1, 1, 0x01, 0x00000001 }, - { 0x0007a3, 1, 0x01, 0x00000001 }, - { 0x0007a4, 2, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, { 0x000831, 1, 0x01, 0x00000004 }, { 0x01e100, 1, 0x01, 0x00000001 }, { 0x001000, 1, 0x01, 0x00000008 }, @@ -273,8 +272,14 @@ nve4_grctx_init_icmd[] = { {} }; -struct nvc0_graph_init -nve4_grctx_init_a097[] = { +const struct nvc0_graph_pack +nve4_grctx_pack_icmd[] = { + { nve4_grctx_init_icmd_0 }, + {} +}; + +const struct nvc0_graph_init +nve4_grctx_init_a097_0[] = { { 0x000800, 8, 0x40, 0x00000000 }, { 0x000804, 8, 0x40, 0x00000000 }, { 0x000808, 8, 0x40, 0x00000400 }, @@ -517,8 +522,7 @@ nve4_grctx_init_a097[] = { { 0x001350, 1, 0x04, 0x00000002 }, { 0x001358, 1, 0x04, 0x00000001 }, { 0x0012e4, 1, 0x04, 0x00000000 }, - { 0x00131c, 1, 0x04, 0x00000000 }, - { 0x001320, 3, 0x04, 0x00000000 }, + { 0x00131c, 4, 0x04, 0x00000000 }, { 0x0019c0, 1, 0x04, 0x00000000 }, { 0x001140, 1, 0x04, 0x00000000 }, { 0x0019c4, 1, 0x04, 0x00000000 }, @@ -574,19 +578,24 @@ nve4_grctx_init_a097[] = { {} }; -static struct nvc0_graph_init -nve4_grctx_init_unk40xx[] = { +static const struct nvc0_graph_pack +nve4_grctx_pack_mthd[] = { + { nve4_grctx_init_a097_0, 0xa097 }, + { nvc0_grctx_init_902d_0, 0x902d }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_fe_0[] = { { 0x404010, 5, 0x04, 0x00000000 }, { 0x404024, 1, 0x04, 0x0000e000 }, { 0x404028, 1, 0x04, 0x00000000 }, - { 0x4040a8, 1, 0x04, 0x00000000 }, - { 0x4040ac, 7, 0x04, 0x00000000 }, + { 0x4040a8, 8, 0x04, 0x00000000 }, { 0x4040c8, 1, 0x04, 0xf800008f }, { 0x4040d0, 6, 0x04, 0x00000000 }, { 0x4040e8, 1, 0x04, 0x00001000 }, { 0x4040f8, 1, 0x04, 0x00000000 }, - { 0x404130, 1, 0x04, 0x00000000 }, - { 0x404134, 1, 0x04, 0x00000000 }, + { 0x404130, 2, 0x04, 0x00000000 }, { 0x404138, 1, 0x04, 0x20000040 }, { 0x404150, 1, 0x04, 0x0000002e }, { 0x404154, 1, 0x04, 0x00000400 }, @@ -597,8 +606,8 @@ nve4_grctx_init_unk40xx[] = { {} }; -struct nvc0_graph_init -nve4_grctx_init_unk46xx[] = { +const struct nvc0_graph_init +nve4_grctx_init_memfmt_0[] = { { 0x404604, 1, 0x04, 0x00000014 }, { 0x404608, 1, 0x04, 0x00000000 }, { 0x40460c, 1, 0x04, 0x00003fff }, @@ -614,11 +623,6 @@ nve4_grctx_init_unk46xx[] = { { 0x4046a0, 1, 0x04, 0x007f0080 }, { 0x4046a4, 8, 0x04, 0x00000000 }, { 0x4046c8, 3, 0x04, 0x00000000 }, - {} -}; - -struct nvc0_graph_init -nve4_grctx_init_unk47xx[] = { { 0x404700, 3, 0x04, 0x00000000 }, { 0x404718, 7, 0x04, 0x00000000 }, { 0x404734, 1, 0x04, 0x00000100 }, @@ -628,8 +632,8 @@ nve4_grctx_init_unk47xx[] = { {} }; -struct nvc0_graph_init -nve4_grctx_init_unk58xx[] = { +const struct nvc0_graph_init +nve4_grctx_init_ds_0[] = { { 0x405800, 1, 0x04, 0x0f8000bf }, { 0x405830, 1, 0x04, 0x02180648 }, { 0x405834, 1, 0x04, 0x08000000 }, @@ -641,22 +645,17 @@ nve4_grctx_init_unk58xx[] = { {} }; -static struct nvc0_graph_init -nve4_grctx_init_unk5bxx[] = { +static const struct nvc0_graph_init +nve4_grctx_init_cwd_0[] = { { 0x405b00, 1, 0x04, 0x00000000 }, { 0x405b10, 1, 0x04, 0x00001000 }, {} }; -static struct nvc0_graph_init -nve4_grctx_init_unk60xx[] = { +static const struct nvc0_graph_init +nve4_grctx_init_pd_0[] = { { 0x406020, 1, 0x04, 0x004103c1 }, { 0x406028, 4, 0x04, 0x00000001 }, - {} -}; - -static struct nvc0_graph_init -nve4_grctx_init_unk64xx[] = { { 0x4064a8, 1, 0x04, 0x00000000 }, { 0x4064ac, 1, 0x04, 0x00003fff }, { 0x4064b4, 2, 0x04, 0x00000000 }, @@ -668,14 +667,14 @@ nve4_grctx_init_unk64xx[] = { {} }; -static struct nvc0_graph_init -nve4_grctx_init_unk70xx[] = { +static const struct nvc0_graph_init +nve4_grctx_init_sked_0[] = { { 0x407040, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nve4_grctx_init_unk80xx[] = { +const struct nvc0_graph_init +nve4_grctx_init_scc_0[] = { { 0x408000, 2, 0x04, 0x00000000 }, { 0x408008, 1, 0x04, 0x00000030 }, { 0x40800c, 2, 0x04, 0x00000000 }, @@ -685,8 +684,8 @@ nve4_grctx_init_unk80xx[] = { {} }; -static struct nvc0_graph_init -nve4_grctx_init_rop[] = { +static const struct nvc0_graph_init +nve4_grctx_init_be_0[] = { { 0x408800, 1, 0x04, 0x02802a3c }, { 0x408804, 1, 0x04, 0x00000040 }, { 0x408808, 1, 0x04, 0x1043e005 }, @@ -698,22 +697,24 @@ nve4_grctx_init_rop[] = { {} }; -static struct nvc0_graph_init -nve4_grctx_init_gpc_0[] = { - { 0x418380, 1, 0x04, 0x00000016 }, - { 0x418400, 1, 0x04, 0x38004e00 }, - { 0x418404, 1, 0x04, 0x71e0ffff }, - { 0x41840c, 1, 0x04, 0x00001008 }, - { 0x418410, 1, 0x04, 0x0fff0fff }, - { 0x418414, 1, 0x04, 0x02200fff }, - { 0x418450, 6, 0x04, 0x00000000 }, - { 0x418468, 1, 0x04, 0x00000001 }, - { 0x41846c, 2, 0x04, 0x00000000 }, - { 0x418600, 1, 0x04, 0x0000001f }, - { 0x418684, 1, 0x04, 0x0000000f }, - { 0x418700, 1, 0x04, 0x00000002 }, - { 0x418704, 1, 0x04, 0x00000080 }, - { 0x418708, 3, 0x04, 0x00000000 }, +const struct nvc0_graph_pack +nve4_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nve4_grctx_init_fe_0 }, + { nvc0_grctx_init_pri_0 }, + { nve4_grctx_init_memfmt_0 }, + { nve4_grctx_init_ds_0 }, + { nve4_grctx_init_cwd_0 }, + { nve4_grctx_init_pd_0 }, + { nve4_grctx_init_sked_0 }, + { nvc0_grctx_init_rstr2d_0 }, + { nve4_grctx_init_scc_0 }, + { nve4_grctx_init_be_0 }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x7006860a }, { 0x418808, 3, 0x04, 0x00000000 }, { 0x418828, 1, 0x04, 0x00000044 }, @@ -722,35 +723,35 @@ nve4_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x20100018 }, - { 0x41891c, 1, 0x04, 0x00ff00ff }, - { 0x418924, 1, 0x04, 0x00000000 }, - { 0x418928, 1, 0x04, 0x00ffff00 }, - { 0x41892c, 1, 0x04, 0x0000ff00 }, - { 0x418b00, 1, 0x04, 0x00000006 }, - { 0x418b08, 1, 0x04, 0x0a418820 }, - { 0x418b0c, 1, 0x04, 0x062080e6 }, - { 0x418b10, 1, 0x04, 0x020398a4 }, - { 0x418b14, 1, 0x04, 0x0e629062 }, - { 0x418b18, 1, 0x04, 0x0a418820 }, - { 0x418b1c, 1, 0x04, 0x000000e6 }, - { 0x418bb8, 1, 0x04, 0x00000103 }, + {} +}; + +const struct nvc0_graph_init +nve4_grctx_init_gpm_0[] = { { 0x418c08, 1, 0x04, 0x00000001 }, { 0x418c10, 8, 0x04, 0x00000000 }, { 0x418c40, 1, 0x04, 0xffffffff }, { 0x418c6c, 1, 0x04, 0x00000001 }, { 0x418c80, 1, 0x04, 0x20200004 }, { 0x418c8c, 1, 0x04, 0x00000001 }, - { 0x419000, 1, 0x04, 0x00000780 }, - { 0x419004, 2, 0x04, 0x00000000 }, - { 0x419014, 1, 0x04, 0x00000004 }, {} }; -static struct nvc0_graph_init -nve4_grctx_init_tpc[] = { - { 0x419848, 1, 0x04, 0x00000000 }, - { 0x419864, 1, 0x04, 0x00000129 }, - { 0x419888, 1, 0x04, 0x00000000 }, +const struct nvc0_graph_pack +nve4_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvd9_grctx_init_prop_0 }, + { nvd9_grctx_init_gpc_unk_1 }, + { nve4_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvd9_grctx_init_crstr_0 }, + { nve4_grctx_init_gpm_0 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000000f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000021 }, @@ -761,14 +762,29 @@ nve4_grctx_init_tpc[] = { { 0x419a20, 1, 0x04, 0x00000800 }, { 0x419a30, 1, 0x04, 0x00000001 }, { 0x419ac4, 1, 0x04, 0x0037f440 }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_mpc_0[] = { { 0x419c00, 1, 0x04, 0x0000000a }, { 0x419c04, 1, 0x04, 0x80000006 }, { 0x419c08, 1, 0x04, 0x00000002 }, { 0x419c20, 1, 0x04, 0x00000000 }, { 0x419c24, 1, 0x04, 0x00084210 }, { 0x419c28, 1, 0x04, 0x3efbefbe }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_l1c_0[] = { { 0x419ce8, 1, 0x04, 0x00000000 }, { 0x419cf4, 1, 0x04, 0x00003203 }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_sm_0[] = { { 0x419e04, 3, 0x04, 0x00000000 }, { 0x419e10, 1, 0x04, 0x00000402 }, { 0x419e44, 1, 0x04, 0x0013eff2 }, @@ -782,29 +798,47 @@ nve4_grctx_init_tpc[] = { { 0x419f58, 1, 0x04, 0x00000000 }, { 0x419f70, 1, 0x04, 0x00000000 }, { 0x419f78, 1, 0x04, 0x0000000b }, - { 0x419f7c, 1, 0x04, 0x0000027a }, + { 0x419f7c, 1, 0x04, 0x0000027c }, {} }; -static struct nvc0_graph_init -nve4_grctx_init_unk[] = { +const struct nvc0_graph_pack +nve4_grctx_pack_tpc[] = { + { nvd7_grctx_init_pe_0 }, + { nve4_grctx_init_tex_0 }, + { nve4_grctx_init_mpc_0 }, + { nve4_grctx_init_l1c_0 }, + { nve4_grctx_init_sm_0 }, + {} +}; + +const struct nvc0_graph_init +nve4_grctx_init_pes_0[] = { { 0x41be24, 1, 0x04, 0x00000006 }, + {} +}; + +static const struct nvc0_graph_init +nve4_grctx_init_cbm_0[] = { { 0x41bec0, 1, 0x04, 0x12180000 }, { 0x41bec4, 1, 0x04, 0x00037f7f }, { 0x41bee4, 1, 0x04, 0x06480430 }, - { 0x41bf00, 1, 0x04, 0x0a418820 }, - { 0x41bf04, 1, 0x04, 0x062080e6 }, - { 0x41bf08, 1, 0x04, 0x020398a4 }, - { 0x41bf0c, 1, 0x04, 0x0e629062 }, - { 0x41bf10, 1, 0x04, 0x0a418820 }, - { 0x41bf14, 1, 0x04, 0x000000e6 }, - { 0x41bfd0, 1, 0x04, 0x00900103 }, - { 0x41bfe0, 1, 0x04, 0x00400001 }, - { 0x41bfe4, 1, 0x04, 0x00000000 }, {} }; -static void +const struct nvc0_graph_pack +nve4_grctx_pack_ppc[] = { + { nve4_grctx_init_pes_0 }, + { nve4_grctx_init_cbm_0 }, + { nvd7_grctx_init_wwdx_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + +void nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { u32 magic[GPC_MAX][2]; @@ -925,10 +959,11 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_mask(priv, 0x000260, 0x00000001, 0x00000000); - for (i = 0; oclass->hub[i]; i++) - nvc0_graph_mmio(priv, oclass->hub[i]); - for (i = 0; oclass->gpc[i]; i++) - nvc0_graph_mmio(priv, oclass->gpc[i]); + nvc0_graph_mmio(priv, oclass->hub); + nvc0_graph_mmio(priv, oclass->gpc); + nvc0_graph_mmio(priv, oclass->zcull); + nvc0_graph_mmio(priv, oclass->tpc); + nvc0_graph_mmio(priv, oclass->ppc); nv_wr32(priv, 0x404154, 0x00000000); @@ -962,41 +997,6 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) nv_mask(priv, 0x41be10, 0x00800000, 0x00800000); } -static struct nvc0_graph_init * -nve4_grctx_init_hub[] = { - nvc0_grctx_init_base, - nve4_grctx_init_unk40xx, - nvc0_grctx_init_unk44xx, - nve4_grctx_init_unk46xx, - nve4_grctx_init_unk47xx, - nve4_grctx_init_unk58xx, - nve4_grctx_init_unk5bxx, - nve4_grctx_init_unk60xx, - nve4_grctx_init_unk64xx, - nve4_grctx_init_unk70xx, - nvc0_grctx_init_unk78xx, - nve4_grctx_init_unk80xx, - nve4_grctx_init_rop, - NULL -}; - -struct nvc0_graph_init * -nve4_grctx_init_gpc[] = { - nve4_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nve4_grctx_init_tpc, - nve4_grctx_init_unk, - NULL -}; - -static struct nvc0_graph_mthd -nve4_grctx_init_mthd[] = { - { 0xa097, nve4_grctx_init_a097, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x902d, nvc0_grctx_init_mthd_magic, }, - {} -}; - struct nouveau_oclass * nve4_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xe4), @@ -1008,11 +1008,14 @@ nve4_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nve4_grctx_generate_main, - .mods = nve4_grctx_generate_mods, - .unkn = nve4_grctx_generate_unkn, - .hub = nve4_grctx_init_hub, - .gpc = nve4_grctx_init_gpc, - .icmd = nve4_grctx_init_icmd, - .mthd = nve4_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nve4_grctx_pack_tpc, + .ppc = nve4_grctx_pack_ppc, + .icmd = nve4_grctx_pack_icmd, + .mthd = nve4_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c index 44012c3da53..dec03f04114 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c @@ -22,10 +22,580 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include "nvc0.h" +#include "ctxnvc0.h" -static struct nvc0_graph_init -nvf0_grctx_init_unk40xx[] = { +/******************************************************************************* + * PGRAPH context register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nvf0_grctx_init_icmd_0[] = { + { 0x001000, 1, 0x01, 0x00000004 }, + { 0x000039, 3, 0x01, 0x00000000 }, + { 0x0000a9, 1, 0x01, 0x0000ffff }, + { 0x000038, 1, 0x01, 0x0fac6881 }, + { 0x00003d, 1, 0x01, 0x00000001 }, + { 0x0000e8, 8, 0x01, 0x00000400 }, + { 0x000078, 8, 0x01, 0x00000300 }, + { 0x000050, 1, 0x01, 0x00000011 }, + { 0x000058, 8, 0x01, 0x00000008 }, + { 0x000208, 8, 0x01, 0x00000001 }, + { 0x000081, 1, 0x01, 0x00000001 }, + { 0x000085, 1, 0x01, 0x00000004 }, + { 0x000088, 1, 0x01, 0x00000400 }, + { 0x000090, 1, 0x01, 0x00000300 }, + { 0x000098, 1, 0x01, 0x00001001 }, + { 0x0000e3, 1, 0x01, 0x00000001 }, + { 0x0000da, 1, 0x01, 0x00000001 }, + { 0x0000f8, 1, 0x01, 0x00000003 }, + { 0x0000fa, 1, 0x01, 0x00000001 }, + { 0x00009f, 4, 0x01, 0x0000ffff }, + { 0x0000b1, 1, 0x01, 0x00000001 }, + { 0x0000ad, 1, 0x01, 0x0000013e }, + { 0x0000e1, 1, 0x01, 0x00000010 }, + { 0x000290, 16, 0x01, 0x00000000 }, + { 0x0003b0, 16, 0x01, 0x00000000 }, + { 0x0002a0, 16, 0x01, 0x00000000 }, + { 0x000420, 16, 0x01, 0x00000000 }, + { 0x0002b0, 16, 0x01, 0x00000000 }, + { 0x000430, 16, 0x01, 0x00000000 }, + { 0x0002c0, 16, 0x01, 0x00000000 }, + { 0x0004d0, 16, 0x01, 0x00000000 }, + { 0x000720, 16, 0x01, 0x00000000 }, + { 0x0008c0, 16, 0x01, 0x00000000 }, + { 0x000890, 16, 0x01, 0x00000000 }, + { 0x0008e0, 16, 0x01, 0x00000000 }, + { 0x0008a0, 16, 0x01, 0x00000000 }, + { 0x0008f0, 16, 0x01, 0x00000000 }, + { 0x00094c, 1, 0x01, 0x000000ff }, + { 0x00094d, 1, 0x01, 0xffffffff }, + { 0x00094e, 1, 0x01, 0x00000002 }, + { 0x0002ec, 1, 0x01, 0x00000001 }, + { 0x0002f2, 2, 0x01, 0x00000001 }, + { 0x0002f5, 1, 0x01, 0x00000001 }, + { 0x0002f7, 1, 0x01, 0x00000001 }, + { 0x000303, 1, 0x01, 0x00000001 }, + { 0x0002e6, 1, 0x01, 0x00000001 }, + { 0x000466, 1, 0x01, 0x00000052 }, + { 0x000301, 1, 0x01, 0x3f800000 }, + { 0x000304, 1, 0x01, 0x30201000 }, + { 0x000305, 1, 0x01, 0x70605040 }, + { 0x000306, 1, 0x01, 0xb8a89888 }, + { 0x000307, 1, 0x01, 0xf8e8d8c8 }, + { 0x00030a, 1, 0x01, 0x00ffff00 }, + { 0x00030b, 1, 0x01, 0x0000001a }, + { 0x00030c, 1, 0x01, 0x00000001 }, + { 0x000318, 1, 0x01, 0x00000001 }, + { 0x000340, 1, 0x01, 0x00000000 }, + { 0x000375, 1, 0x01, 0x00000001 }, + { 0x00037d, 1, 0x01, 0x00000006 }, + { 0x0003a0, 1, 0x01, 0x00000002 }, + { 0x0003aa, 1, 0x01, 0x00000001 }, + { 0x0003a9, 1, 0x01, 0x00000001 }, + { 0x000380, 1, 0x01, 0x00000001 }, + { 0x000383, 1, 0x01, 0x00000011 }, + { 0x000360, 1, 0x01, 0x00000040 }, + { 0x000366, 2, 0x01, 0x00000000 }, + { 0x000368, 1, 0x01, 0x00000fff }, + { 0x000370, 2, 0x01, 0x00000000 }, + { 0x000372, 1, 0x01, 0x000fffff }, + { 0x00037a, 1, 0x01, 0x00000012 }, + { 0x000619, 1, 0x01, 0x00000003 }, + { 0x000811, 1, 0x01, 0x00000003 }, + { 0x000812, 1, 0x01, 0x00000004 }, + { 0x000813, 1, 0x01, 0x00000006 }, + { 0x000814, 1, 0x01, 0x00000008 }, + { 0x000815, 1, 0x01, 0x0000000b }, + { 0x000800, 6, 0x01, 0x00000001 }, + { 0x000632, 1, 0x01, 0x00000001 }, + { 0x000633, 1, 0x01, 0x00000002 }, + { 0x000634, 1, 0x01, 0x00000003 }, + { 0x000635, 1, 0x01, 0x00000004 }, + { 0x000654, 1, 0x01, 0x3f800000 }, + { 0x000657, 1, 0x01, 0x3f800000 }, + { 0x000655, 2, 0x01, 0x3f800000 }, + { 0x0006cd, 1, 0x01, 0x3f800000 }, + { 0x0007f5, 1, 0x01, 0x3f800000 }, + { 0x0007dc, 1, 0x01, 0x39291909 }, + { 0x0007dd, 1, 0x01, 0x79695949 }, + { 0x0007de, 1, 0x01, 0xb9a99989 }, + { 0x0007df, 1, 0x01, 0xf9e9d9c9 }, + { 0x0007e8, 1, 0x01, 0x00003210 }, + { 0x0007e9, 1, 0x01, 0x00007654 }, + { 0x0007ea, 1, 0x01, 0x00000098 }, + { 0x0007ec, 1, 0x01, 0x39291909 }, + { 0x0007ed, 1, 0x01, 0x79695949 }, + { 0x0007ee, 1, 0x01, 0xb9a99989 }, + { 0x0007ef, 1, 0x01, 0xf9e9d9c9 }, + { 0x0007f0, 1, 0x01, 0x00003210 }, + { 0x0007f1, 1, 0x01, 0x00007654 }, + { 0x0007f2, 1, 0x01, 0x00000098 }, + { 0x0005a5, 1, 0x01, 0x00000001 }, + { 0x000980, 128, 0x01, 0x00000000 }, + { 0x000468, 1, 0x01, 0x00000004 }, + { 0x00046c, 1, 0x01, 0x00000001 }, + { 0x000470, 96, 0x01, 0x00000000 }, + { 0x000510, 16, 0x01, 0x3f800000 }, + { 0x000520, 1, 0x01, 0x000002b6 }, + { 0x000529, 1, 0x01, 0x00000001 }, + { 0x000530, 16, 0x01, 0xffff0000 }, + { 0x000585, 1, 0x01, 0x0000003f }, + { 0x000576, 1, 0x01, 0x00000003 }, + { 0x00057b, 1, 0x01, 0x00000059 }, + { 0x000586, 1, 0x01, 0x00000040 }, + { 0x000582, 2, 0x01, 0x00000080 }, + { 0x0005c2, 1, 0x01, 0x00000001 }, + { 0x000638, 2, 0x01, 0x00000001 }, + { 0x00063a, 1, 0x01, 0x00000002 }, + { 0x00063b, 2, 0x01, 0x00000001 }, + { 0x00063d, 1, 0x01, 0x00000002 }, + { 0x00063e, 1, 0x01, 0x00000001 }, + { 0x0008b8, 8, 0x01, 0x00000001 }, + { 0x000900, 8, 0x01, 0x00000001 }, + { 0x000908, 8, 0x01, 0x00000002 }, + { 0x000910, 16, 0x01, 0x00000001 }, + { 0x000920, 8, 0x01, 0x00000002 }, + { 0x000928, 8, 0x01, 0x00000001 }, + { 0x000662, 1, 0x01, 0x00000001 }, + { 0x000648, 9, 0x01, 0x00000001 }, + { 0x000658, 1, 0x01, 0x0000000f }, + { 0x0007ff, 1, 0x01, 0x0000000a }, + { 0x00066a, 1, 0x01, 0x40000000 }, + { 0x00066b, 1, 0x01, 0x10000000 }, + { 0x00066c, 2, 0x01, 0xffff0000 }, + { 0x0007af, 2, 0x01, 0x00000008 }, + { 0x0007f6, 1, 0x01, 0x00000001 }, + { 0x00080b, 1, 0x01, 0x00000002 }, + { 0x0006b2, 1, 0x01, 0x00000055 }, + { 0x0007ad, 1, 0x01, 0x00000003 }, + { 0x000937, 1, 0x01, 0x00000001 }, + { 0x000971, 1, 0x01, 0x00000008 }, + { 0x000972, 1, 0x01, 0x00000040 }, + { 0x000973, 1, 0x01, 0x0000012c }, + { 0x00097c, 1, 0x01, 0x00000040 }, + { 0x000979, 1, 0x01, 0x00000003 }, + { 0x000975, 1, 0x01, 0x00000020 }, + { 0x000976, 1, 0x01, 0x00000001 }, + { 0x000977, 1, 0x01, 0x00000020 }, + { 0x000978, 1, 0x01, 0x00000001 }, + { 0x000957, 1, 0x01, 0x00000003 }, + { 0x00095e, 1, 0x01, 0x20164010 }, + { 0x00095f, 1, 0x01, 0x00000020 }, + { 0x000a0d, 1, 0x01, 0x00000006 }, + { 0x00097d, 1, 0x01, 0x00000020 }, + { 0x000683, 1, 0x01, 0x00000006 }, + { 0x000685, 1, 0x01, 0x003fffff }, + { 0x000687, 1, 0x01, 0x003fffff }, + { 0x0006a0, 1, 0x01, 0x00000005 }, + { 0x000840, 1, 0x01, 0x00400008 }, + { 0x000841, 1, 0x01, 0x08000080 }, + { 0x000842, 1, 0x01, 0x00400008 }, + { 0x000843, 1, 0x01, 0x08000080 }, + { 0x0006aa, 1, 0x01, 0x00000001 }, + { 0x0006ab, 1, 0x01, 0x00000002 }, + { 0x0006ac, 1, 0x01, 0x00000080 }, + { 0x0006ad, 2, 0x01, 0x00000100 }, + { 0x0006b1, 1, 0x01, 0x00000011 }, + { 0x0006bb, 1, 0x01, 0x000000cf }, + { 0x0006ce, 1, 0x01, 0x2a712488 }, + { 0x000739, 1, 0x01, 0x4085c000 }, + { 0x00073a, 1, 0x01, 0x00000080 }, + { 0x000786, 1, 0x01, 0x80000100 }, + { 0x00073c, 1, 0x01, 0x00010100 }, + { 0x00073d, 1, 0x01, 0x02800000 }, + { 0x000787, 1, 0x01, 0x000000cf }, + { 0x00078c, 1, 0x01, 0x00000008 }, + { 0x000792, 1, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, + { 0x000797, 1, 0x01, 0x000000cf }, + { 0x000836, 1, 0x01, 0x00000001 }, + { 0x00079a, 1, 0x01, 0x00000002 }, + { 0x000833, 1, 0x01, 0x04444480 }, + { 0x0007a1, 1, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, + { 0x000831, 1, 0x01, 0x00000004 }, + { 0x000b07, 1, 0x01, 0x00000002 }, + { 0x000b08, 2, 0x01, 0x00000100 }, + { 0x000b0a, 1, 0x01, 0x00000001 }, + { 0x000a04, 1, 0x01, 0x000000ff }, + { 0x000a0b, 1, 0x01, 0x00000040 }, + { 0x00097f, 1, 0x01, 0x00000100 }, + { 0x000a02, 1, 0x01, 0x00000001 }, + { 0x000809, 1, 0x01, 0x00000007 }, + { 0x00c221, 1, 0x01, 0x00000040 }, + { 0x00c1b0, 8, 0x01, 0x0000000f }, + { 0x00c1b8, 1, 0x01, 0x0fac6881 }, + { 0x00c1b9, 1, 0x01, 0x00fac688 }, + { 0x00c401, 1, 0x01, 0x00000001 }, + { 0x00c402, 1, 0x01, 0x00010001 }, + { 0x00c403, 2, 0x01, 0x00000001 }, + { 0x00c40e, 1, 0x01, 0x00000020 }, + { 0x00c500, 1, 0x01, 0x00000003 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + { 0x001000, 1, 0x01, 0x00000002 }, + { 0x0006aa, 1, 0x01, 0x00000001 }, + { 0x0006ad, 2, 0x01, 0x00000100 }, + { 0x0006b1, 1, 0x01, 0x00000011 }, + { 0x00078c, 1, 0x01, 0x00000008 }, + { 0x000792, 1, 0x01, 0x00000001 }, + { 0x000794, 3, 0x01, 0x00000001 }, + { 0x000797, 1, 0x01, 0x000000cf }, + { 0x00079a, 1, 0x01, 0x00000002 }, + { 0x000833, 1, 0x01, 0x04444480 }, + { 0x0007a1, 1, 0x01, 0x00000001 }, + { 0x0007a3, 3, 0x01, 0x00000001 }, + { 0x000831, 1, 0x01, 0x00000004 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + { 0x001000, 1, 0x01, 0x00000008 }, + { 0x000039, 3, 0x01, 0x00000000 }, + { 0x000380, 1, 0x01, 0x00000001 }, + { 0x000366, 2, 0x01, 0x00000000 }, + { 0x000368, 1, 0x01, 0x00000fff }, + { 0x000370, 2, 0x01, 0x00000000 }, + { 0x000372, 1, 0x01, 0x000fffff }, + { 0x000813, 1, 0x01, 0x00000006 }, + { 0x000814, 1, 0x01, 0x00000008 }, + { 0x000957, 1, 0x01, 0x00000003 }, + { 0x000b07, 1, 0x01, 0x00000002 }, + { 0x000b08, 2, 0x01, 0x00000100 }, + { 0x000b0a, 1, 0x01, 0x00000001 }, + { 0x000a04, 1, 0x01, 0x000000ff }, + { 0x000a0b, 1, 0x01, 0x00000040 }, + { 0x00097f, 1, 0x01, 0x00000100 }, + { 0x000a02, 1, 0x01, 0x00000001 }, + { 0x000809, 1, 0x01, 0x00000007 }, + { 0x00c221, 1, 0x01, 0x00000040 }, + { 0x00c401, 1, 0x01, 0x00000001 }, + { 0x00c402, 1, 0x01, 0x00010001 }, + { 0x00c403, 2, 0x01, 0x00000001 }, + { 0x00c40e, 1, 0x01, 0x00000020 }, + { 0x00c500, 1, 0x01, 0x00000003 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + { 0x001000, 1, 0x01, 0x00000001 }, + { 0x000b07, 1, 0x01, 0x00000002 }, + { 0x000b08, 2, 0x01, 0x00000100 }, + { 0x000b0a, 1, 0x01, 0x00000001 }, + { 0x01e100, 1, 0x01, 0x00000001 }, + {} +}; + +static const struct nvc0_graph_pack +nvf0_grctx_pack_icmd[] = { + { nvf0_grctx_init_icmd_0 }, + {} +}; + +static const struct nvc0_graph_init +nvf0_grctx_init_a197_0[] = { + { 0x000800, 8, 0x40, 0x00000000 }, + { 0x000804, 8, 0x40, 0x00000000 }, + { 0x000808, 8, 0x40, 0x00000400 }, + { 0x00080c, 8, 0x40, 0x00000300 }, + { 0x000810, 1, 0x04, 0x000000cf }, + { 0x000850, 7, 0x40, 0x00000000 }, + { 0x000814, 8, 0x40, 0x00000040 }, + { 0x000818, 8, 0x40, 0x00000001 }, + { 0x00081c, 8, 0x40, 0x00000000 }, + { 0x000820, 8, 0x40, 0x00000000 }, + { 0x001c00, 16, 0x10, 0x00000000 }, + { 0x001c04, 16, 0x10, 0x00000000 }, + { 0x001c08, 16, 0x10, 0x00000000 }, + { 0x001c0c, 16, 0x10, 0x00000000 }, + { 0x001d00, 16, 0x10, 0x00000000 }, + { 0x001d04, 16, 0x10, 0x00000000 }, + { 0x001d08, 16, 0x10, 0x00000000 }, + { 0x001d0c, 16, 0x10, 0x00000000 }, + { 0x001f00, 16, 0x08, 0x00000000 }, + { 0x001f04, 16, 0x08, 0x00000000 }, + { 0x001f80, 16, 0x08, 0x00000000 }, + { 0x001f84, 16, 0x08, 0x00000000 }, + { 0x002000, 1, 0x04, 0x00000000 }, + { 0x002040, 1, 0x04, 0x00000011 }, + { 0x002080, 1, 0x04, 0x00000020 }, + { 0x0020c0, 1, 0x04, 0x00000030 }, + { 0x002100, 1, 0x04, 0x00000040 }, + { 0x002140, 1, 0x04, 0x00000051 }, + { 0x00200c, 6, 0x40, 0x00000001 }, + { 0x002010, 1, 0x04, 0x00000000 }, + { 0x002050, 1, 0x04, 0x00000000 }, + { 0x002090, 1, 0x04, 0x00000001 }, + { 0x0020d0, 1, 0x04, 0x00000002 }, + { 0x002110, 1, 0x04, 0x00000003 }, + { 0x002150, 1, 0x04, 0x00000004 }, + { 0x000380, 4, 0x20, 0x00000000 }, + { 0x000384, 4, 0x20, 0x00000000 }, + { 0x000388, 4, 0x20, 0x00000000 }, + { 0x00038c, 4, 0x20, 0x00000000 }, + { 0x000700, 4, 0x10, 0x00000000 }, + { 0x000704, 4, 0x10, 0x00000000 }, + { 0x000708, 4, 0x10, 0x00000000 }, + { 0x002800, 128, 0x04, 0x00000000 }, + { 0x000a00, 16, 0x20, 0x00000000 }, + { 0x000a04, 16, 0x20, 0x00000000 }, + { 0x000a08, 16, 0x20, 0x00000000 }, + { 0x000a0c, 16, 0x20, 0x00000000 }, + { 0x000a10, 16, 0x20, 0x00000000 }, + { 0x000a14, 16, 0x20, 0x00000000 }, + { 0x000c00, 16, 0x10, 0x00000000 }, + { 0x000c04, 16, 0x10, 0x00000000 }, + { 0x000c08, 16, 0x10, 0x00000000 }, + { 0x000c0c, 16, 0x10, 0x3f800000 }, + { 0x000d00, 8, 0x08, 0xffff0000 }, + { 0x000d04, 8, 0x08, 0xffff0000 }, + { 0x000e00, 16, 0x10, 0x00000000 }, + { 0x000e04, 16, 0x10, 0xffff0000 }, + { 0x000e08, 16, 0x10, 0xffff0000 }, + { 0x000d40, 4, 0x08, 0x00000000 }, + { 0x000d44, 4, 0x08, 0x00000000 }, + { 0x001e00, 8, 0x20, 0x00000001 }, + { 0x001e04, 8, 0x20, 0x00000001 }, + { 0x001e08, 8, 0x20, 0x00000002 }, + { 0x001e0c, 8, 0x20, 0x00000001 }, + { 0x001e10, 8, 0x20, 0x00000001 }, + { 0x001e14, 8, 0x20, 0x00000002 }, + { 0x001e18, 8, 0x20, 0x00000001 }, + { 0x003400, 128, 0x04, 0x00000000 }, + { 0x00030c, 1, 0x04, 0x00000001 }, + { 0x001944, 1, 0x04, 0x00000000 }, + { 0x001514, 1, 0x04, 0x00000000 }, + { 0x000d68, 1, 0x04, 0x0000ffff }, + { 0x00121c, 1, 0x04, 0x0fac6881 }, + { 0x000fac, 1, 0x04, 0x00000001 }, + { 0x001538, 1, 0x04, 0x00000001 }, + { 0x000fe0, 2, 0x04, 0x00000000 }, + { 0x000fe8, 1, 0x04, 0x00000014 }, + { 0x000fec, 1, 0x04, 0x00000040 }, + { 0x000ff0, 1, 0x04, 0x00000000 }, + { 0x00179c, 1, 0x04, 0x00000000 }, + { 0x001228, 1, 0x04, 0x00000400 }, + { 0x00122c, 1, 0x04, 0x00000300 }, + { 0x001230, 1, 0x04, 0x00010001 }, + { 0x0007f8, 1, 0x04, 0x00000000 }, + { 0x0015b4, 1, 0x04, 0x00000001 }, + { 0x0015cc, 1, 0x04, 0x00000000 }, + { 0x001534, 1, 0x04, 0x00000000 }, + { 0x000fb0, 1, 0x04, 0x00000000 }, + { 0x0015d0, 1, 0x04, 0x00000000 }, + { 0x00153c, 1, 0x04, 0x00000000 }, + { 0x0016b4, 1, 0x04, 0x00000003 }, + { 0x000fbc, 4, 0x04, 0x0000ffff }, + { 0x000df8, 2, 0x04, 0x00000000 }, + { 0x001948, 1, 0x04, 0x00000000 }, + { 0x001970, 1, 0x04, 0x00000001 }, + { 0x00161c, 1, 0x04, 0x000009f0 }, + { 0x000dcc, 1, 0x04, 0x00000010 }, + { 0x00163c, 1, 0x04, 0x00000000 }, + { 0x0015e4, 1, 0x04, 0x00000000 }, + { 0x001160, 32, 0x04, 0x25e00040 }, + { 0x001880, 32, 0x04, 0x00000000 }, + { 0x000f84, 2, 0x04, 0x00000000 }, + { 0x0017c8, 2, 0x04, 0x00000000 }, + { 0x0017d0, 1, 0x04, 0x000000ff }, + { 0x0017d4, 1, 0x04, 0xffffffff }, + { 0x0017d8, 1, 0x04, 0x00000002 }, + { 0x0017dc, 1, 0x04, 0x00000000 }, + { 0x0015f4, 2, 0x04, 0x00000000 }, + { 0x001434, 2, 0x04, 0x00000000 }, + { 0x000d74, 1, 0x04, 0x00000000 }, + { 0x000dec, 1, 0x04, 0x00000001 }, + { 0x0013a4, 1, 0x04, 0x00000000 }, + { 0x001318, 1, 0x04, 0x00000001 }, + { 0x001644, 1, 0x04, 0x00000000 }, + { 0x000748, 1, 0x04, 0x00000000 }, + { 0x000de8, 1, 0x04, 0x00000000 }, + { 0x001648, 1, 0x04, 0x00000000 }, + { 0x0012a4, 1, 0x04, 0x00000000 }, + { 0x001120, 4, 0x04, 0x00000000 }, + { 0x001118, 1, 0x04, 0x00000000 }, + { 0x00164c, 1, 0x04, 0x00000000 }, + { 0x001658, 1, 0x04, 0x00000000 }, + { 0x001910, 1, 0x04, 0x00000290 }, + { 0x001518, 1, 0x04, 0x00000000 }, + { 0x00165c, 1, 0x04, 0x00000001 }, + { 0x001520, 1, 0x04, 0x00000000 }, + { 0x001604, 1, 0x04, 0x00000000 }, + { 0x001570, 1, 0x04, 0x00000000 }, + { 0x0013b0, 2, 0x04, 0x3f800000 }, + { 0x00020c, 1, 0x04, 0x00000000 }, + { 0x001670, 1, 0x04, 0x30201000 }, + { 0x001674, 1, 0x04, 0x70605040 }, + { 0x001678, 1, 0x04, 0xb8a89888 }, + { 0x00167c, 1, 0x04, 0xf8e8d8c8 }, + { 0x00166c, 1, 0x04, 0x00000000 }, + { 0x001680, 1, 0x04, 0x00ffff00 }, + { 0x0012d0, 1, 0x04, 0x00000003 }, + { 0x0012d4, 1, 0x04, 0x00000002 }, + { 0x001684, 2, 0x04, 0x00000000 }, + { 0x000dac, 2, 0x04, 0x00001b02 }, + { 0x000db4, 1, 0x04, 0x00000000 }, + { 0x00168c, 1, 0x04, 0x00000000 }, + { 0x0015bc, 1, 0x04, 0x00000000 }, + { 0x00156c, 1, 0x04, 0x00000000 }, + { 0x00187c, 1, 0x04, 0x00000000 }, + { 0x001110, 1, 0x04, 0x00000001 }, + { 0x000dc0, 3, 0x04, 0x00000000 }, + { 0x001234, 1, 0x04, 0x00000000 }, + { 0x001690, 1, 0x04, 0x00000000 }, + { 0x0012ac, 1, 0x04, 0x00000001 }, + { 0x0002c4, 1, 0x04, 0x00000000 }, + { 0x000790, 5, 0x04, 0x00000000 }, + { 0x00077c, 1, 0x04, 0x00000000 }, + { 0x001000, 1, 0x04, 0x00000010 }, + { 0x0010fc, 1, 0x04, 0x00000000 }, + { 0x001290, 1, 0x04, 0x00000000 }, + { 0x000218, 1, 0x04, 0x00000010 }, + { 0x0012d8, 1, 0x04, 0x00000000 }, + { 0x0012dc, 1, 0x04, 0x00000010 }, + { 0x000d94, 1, 0x04, 0x00000001 }, + { 0x00155c, 2, 0x04, 0x00000000 }, + { 0x001564, 1, 0x04, 0x00000fff }, + { 0x001574, 2, 0x04, 0x00000000 }, + { 0x00157c, 1, 0x04, 0x000fffff }, + { 0x001354, 1, 0x04, 0x00000000 }, + { 0x001610, 1, 0x04, 0x00000012 }, + { 0x001608, 2, 0x04, 0x00000000 }, + { 0x00260c, 1, 0x04, 0x00000000 }, + { 0x0007ac, 1, 0x04, 0x00000000 }, + { 0x00162c, 1, 0x04, 0x00000003 }, + { 0x000210, 1, 0x04, 0x00000000 }, + { 0x000320, 1, 0x04, 0x00000000 }, + { 0x000324, 6, 0x04, 0x3f800000 }, + { 0x000750, 1, 0x04, 0x00000000 }, + { 0x000760, 1, 0x04, 0x39291909 }, + { 0x000764, 1, 0x04, 0x79695949 }, + { 0x000768, 1, 0x04, 0xb9a99989 }, + { 0x00076c, 1, 0x04, 0xf9e9d9c9 }, + { 0x000770, 1, 0x04, 0x30201000 }, + { 0x000774, 1, 0x04, 0x70605040 }, + { 0x000778, 1, 0x04, 0x00009080 }, + { 0x000780, 1, 0x04, 0x39291909 }, + { 0x000784, 1, 0x04, 0x79695949 }, + { 0x000788, 1, 0x04, 0xb9a99989 }, + { 0x00078c, 1, 0x04, 0xf9e9d9c9 }, + { 0x0007d0, 1, 0x04, 0x30201000 }, + { 0x0007d4, 1, 0x04, 0x70605040 }, + { 0x0007d8, 1, 0x04, 0x00009080 }, + { 0x00037c, 1, 0x04, 0x00000001 }, + { 0x000740, 2, 0x04, 0x00000000 }, + { 0x002600, 1, 0x04, 0x00000000 }, + { 0x001918, 1, 0x04, 0x00000000 }, + { 0x00191c, 1, 0x04, 0x00000900 }, + { 0x001920, 1, 0x04, 0x00000405 }, + { 0x001308, 1, 0x04, 0x00000001 }, + { 0x001924, 1, 0x04, 0x00000000 }, + { 0x0013ac, 1, 0x04, 0x00000000 }, + { 0x00192c, 1, 0x04, 0x00000001 }, + { 0x00193c, 1, 0x04, 0x00002c1c }, + { 0x000d7c, 1, 0x04, 0x00000000 }, + { 0x000f8c, 1, 0x04, 0x00000000 }, + { 0x0002c0, 1, 0x04, 0x00000001 }, + { 0x001510, 1, 0x04, 0x00000000 }, + { 0x001940, 1, 0x04, 0x00000000 }, + { 0x000ff4, 2, 0x04, 0x00000000 }, + { 0x00194c, 2, 0x04, 0x00000000 }, + { 0x001968, 1, 0x04, 0x00000000 }, + { 0x001590, 1, 0x04, 0x0000003f }, + { 0x0007e8, 4, 0x04, 0x00000000 }, + { 0x00196c, 1, 0x04, 0x00000011 }, + { 0x0002e4, 1, 0x04, 0x0000b001 }, + { 0x00036c, 2, 0x04, 0x00000000 }, + { 0x00197c, 1, 0x04, 0x00000000 }, + { 0x000fcc, 2, 0x04, 0x00000000 }, + { 0x0002d8, 1, 0x04, 0x00000040 }, + { 0x001980, 1, 0x04, 0x00000080 }, + { 0x001504, 1, 0x04, 0x00000080 }, + { 0x001984, 1, 0x04, 0x00000000 }, + { 0x000300, 1, 0x04, 0x00000001 }, + { 0x0013a8, 1, 0x04, 0x00000000 }, + { 0x0012ec, 1, 0x04, 0x00000000 }, + { 0x001310, 1, 0x04, 0x00000000 }, + { 0x001314, 1, 0x04, 0x00000001 }, + { 0x001380, 1, 0x04, 0x00000000 }, + { 0x001384, 4, 0x04, 0x00000001 }, + { 0x001394, 1, 0x04, 0x00000000 }, + { 0x00139c, 1, 0x04, 0x00000000 }, + { 0x001398, 1, 0x04, 0x00000000 }, + { 0x001594, 1, 0x04, 0x00000000 }, + { 0x001598, 4, 0x04, 0x00000001 }, + { 0x000f54, 3, 0x04, 0x00000000 }, + { 0x0019bc, 1, 0x04, 0x00000000 }, + { 0x000f9c, 2, 0x04, 0x00000000 }, + { 0x0012cc, 1, 0x04, 0x00000000 }, + { 0x0012e8, 1, 0x04, 0x00000000 }, + { 0x00130c, 1, 0x04, 0x00000001 }, + { 0x001360, 8, 0x04, 0x00000000 }, + { 0x00133c, 2, 0x04, 0x00000001 }, + { 0x001344, 1, 0x04, 0x00000002 }, + { 0x001348, 2, 0x04, 0x00000001 }, + { 0x001350, 1, 0x04, 0x00000002 }, + { 0x001358, 1, 0x04, 0x00000001 }, + { 0x0012e4, 1, 0x04, 0x00000000 }, + { 0x00131c, 4, 0x04, 0x00000000 }, + { 0x0019c0, 1, 0x04, 0x00000000 }, + { 0x001140, 1, 0x04, 0x00000000 }, + { 0x0019c4, 1, 0x04, 0x00000000 }, + { 0x0019c8, 1, 0x04, 0x00001500 }, + { 0x00135c, 1, 0x04, 0x00000000 }, + { 0x000f90, 1, 0x04, 0x00000000 }, + { 0x0019e0, 8, 0x04, 0x00000001 }, + { 0x0019cc, 1, 0x04, 0x00000001 }, + { 0x0015b8, 1, 0x04, 0x00000000 }, + { 0x001a00, 1, 0x04, 0x00001111 }, + { 0x001a04, 7, 0x04, 0x00000000 }, + { 0x000d6c, 2, 0x04, 0xffff0000 }, + { 0x0010f8, 1, 0x04, 0x00001010 }, + { 0x000d80, 5, 0x04, 0x00000000 }, + { 0x000da0, 1, 0x04, 0x00000000 }, + { 0x0007a4, 2, 0x04, 0x00000000 }, + { 0x001508, 1, 0x04, 0x80000000 }, + { 0x00150c, 1, 0x04, 0x40000000 }, + { 0x001668, 1, 0x04, 0x00000000 }, + { 0x000318, 2, 0x04, 0x00000008 }, + { 0x000d9c, 1, 0x04, 0x00000001 }, + { 0x000ddc, 1, 0x04, 0x00000002 }, + { 0x000374, 1, 0x04, 0x00000000 }, + { 0x000378, 1, 0x04, 0x00000020 }, + { 0x0007dc, 1, 0x04, 0x00000000 }, + { 0x00074c, 1, 0x04, 0x00000055 }, + { 0x001420, 1, 0x04, 0x00000003 }, + { 0x0017bc, 2, 0x04, 0x00000000 }, + { 0x0017c4, 1, 0x04, 0x00000001 }, + { 0x001008, 1, 0x04, 0x00000008 }, + { 0x00100c, 1, 0x04, 0x00000040 }, + { 0x001010, 1, 0x04, 0x0000012c }, + { 0x000d60, 1, 0x04, 0x00000040 }, + { 0x00075c, 1, 0x04, 0x00000003 }, + { 0x001018, 1, 0x04, 0x00000020 }, + { 0x00101c, 1, 0x04, 0x00000001 }, + { 0x001020, 1, 0x04, 0x00000020 }, + { 0x001024, 1, 0x04, 0x00000001 }, + { 0x001444, 3, 0x04, 0x00000000 }, + { 0x000360, 1, 0x04, 0x20164010 }, + { 0x000364, 1, 0x04, 0x00000020 }, + { 0x000368, 1, 0x04, 0x00000000 }, + { 0x000de4, 1, 0x04, 0x00000000 }, + { 0x000204, 1, 0x04, 0x00000006 }, + { 0x000208, 1, 0x04, 0x00000000 }, + { 0x0002cc, 2, 0x04, 0x003fffff }, + { 0x001220, 1, 0x04, 0x00000005 }, + { 0x000fdc, 1, 0x04, 0x00000000 }, + { 0x000f98, 1, 0x04, 0x00400008 }, + { 0x001284, 1, 0x04, 0x08000080 }, + { 0x001450, 1, 0x04, 0x00400008 }, + { 0x001454, 1, 0x04, 0x08000080 }, + { 0x000214, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_pack +nvf0_grctx_pack_mthd[] = { + { nvf0_grctx_init_a197_0, 0xa197 }, + { nvc0_grctx_init_902d_0, 0x902d }, + {} +}; + +static const struct nvc0_graph_init +nvf0_grctx_init_fe_0[] = { { 0x404004, 8, 0x04, 0x00000000 }, { 0x404024, 1, 0x04, 0x0000e000 }, { 0x404028, 8, 0x04, 0x00000000 }, @@ -50,8 +620,8 @@ nvf0_grctx_init_unk40xx[] = { {} }; -struct nvc0_graph_init -nvf0_grctx_init_unk44xx[] = { +const struct nvc0_graph_init +nvf0_grctx_init_pri_0[] = { { 0x404404, 12, 0x04, 0x00000000 }, { 0x404438, 1, 0x04, 0x00000000 }, { 0x404460, 2, 0x04, 0x00000000 }, @@ -62,23 +632,18 @@ nvf0_grctx_init_unk44xx[] = { {} }; -struct nvc0_graph_init -nvf0_grctx_init_unk5bxx[] = { +const struct nvc0_graph_init +nvf0_grctx_init_cwd_0[] = { { 0x405b00, 1, 0x04, 0x00000000 }, { 0x405b10, 1, 0x04, 0x00001000 }, { 0x405b20, 1, 0x04, 0x04000000 }, {} }; -struct nvc0_graph_init -nvf0_grctx_init_unk60xx[] = { +static const struct nvc0_graph_init +nvf0_grctx_init_pd_0[] = { { 0x406020, 1, 0x04, 0x034103c1 }, { 0x406028, 4, 0x04, 0x00000001 }, - {} -}; - -static struct nvc0_graph_init -nvf0_grctx_init_unk64xx[] = { { 0x4064a8, 1, 0x04, 0x00000000 }, { 0x4064ac, 1, 0x04, 0x00003fff }, { 0x4064b0, 3, 0x04, 0x00000000 }, @@ -90,8 +655,8 @@ nvf0_grctx_init_unk64xx[] = { {} }; -static struct nvc0_graph_init -nvf0_grctx_init_unk88xx[] = { +static const struct nvc0_graph_init +nvf0_grctx_init_be_0[] = { { 0x408800, 1, 0x04, 0x12802a3c }, { 0x408804, 1, 0x04, 0x00000040 }, { 0x408808, 1, 0x04, 0x1003e005 }, @@ -103,22 +668,23 @@ nvf0_grctx_init_unk88xx[] = { {} }; -static struct nvc0_graph_init -nvf0_grctx_init_gpc_0[] = { - { 0x418380, 1, 0x04, 0x00000016 }, - { 0x418400, 1, 0x04, 0x38004e00 }, - { 0x418404, 1, 0x04, 0x71e0ffff }, - { 0x41840c, 1, 0x04, 0x00001008 }, - { 0x418410, 1, 0x04, 0x0fff0fff }, - { 0x418414, 1, 0x04, 0x02200fff }, - { 0x418450, 6, 0x04, 0x00000000 }, - { 0x418468, 1, 0x04, 0x00000001 }, - { 0x41846c, 2, 0x04, 0x00000000 }, - { 0x418600, 1, 0x04, 0x0000001f }, - { 0x418684, 1, 0x04, 0x0000000f }, - { 0x418700, 1, 0x04, 0x00000002 }, - { 0x418704, 1, 0x04, 0x00000080 }, - { 0x418708, 3, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nvf0_grctx_pack_hub[] = { + { nvc0_grctx_init_main_0 }, + { nvf0_grctx_init_fe_0 }, + { nvf0_grctx_init_pri_0 }, + { nve4_grctx_init_memfmt_0 }, + { nve4_grctx_init_ds_0 }, + { nvf0_grctx_init_cwd_0 }, + { nvf0_grctx_init_pd_0 }, + { nvc0_grctx_init_rstr2d_0 }, + { nve4_grctx_init_scc_0 }, + { nvf0_grctx_init_be_0 }, + {} +}; + +static const struct nvc0_graph_init +nvf0_grctx_init_setup_0[] = { { 0x418800, 1, 0x04, 0x7006860a }, { 0x418808, 1, 0x04, 0x00000000 }, { 0x41880c, 1, 0x04, 0x00000030 }, @@ -129,36 +695,31 @@ nvf0_grctx_init_gpc_0[] = { { 0x4188e0, 1, 0x04, 0x01000000 }, { 0x4188e8, 5, 0x04, 0x00000000 }, { 0x4188fc, 1, 0x04, 0x20100018 }, - { 0x41891c, 1, 0x04, 0x00ff00ff }, - { 0x418924, 1, 0x04, 0x00000000 }, - { 0x418928, 1, 0x04, 0x00ffff00 }, - { 0x41892c, 1, 0x04, 0x0000ff00 }, - { 0x418b00, 1, 0x04, 0x00000006 }, - { 0x418b08, 1, 0x04, 0x0a418820 }, - { 0x418b0c, 1, 0x04, 0x062080e6 }, - { 0x418b10, 1, 0x04, 0x020398a4 }, - { 0x418b14, 1, 0x04, 0x0e629062 }, - { 0x418b18, 1, 0x04, 0x0a418820 }, - { 0x418b1c, 1, 0x04, 0x000000e6 }, - { 0x418bb8, 1, 0x04, 0x00000103 }, - { 0x418c08, 1, 0x04, 0x00000001 }, - { 0x418c10, 8, 0x04, 0x00000000 }, - { 0x418c40, 1, 0x04, 0xffffffff }, - { 0x418c6c, 1, 0x04, 0x00000001 }, - { 0x418c80, 1, 0x04, 0x20200004 }, - { 0x418c8c, 1, 0x04, 0x00000001 }, + {} +}; + +const struct nvc0_graph_init +nvf0_grctx_init_gpc_unk_2[] = { { 0x418d24, 1, 0x04, 0x00000000 }, - { 0x419000, 1, 0x04, 0x00000780 }, - { 0x419004, 2, 0x04, 0x00000000 }, - { 0x419014, 1, 0x04, 0x00000004 }, {} }; -static struct nvc0_graph_init -nvf0_grctx_init_tpc[] = { - { 0x419848, 1, 0x04, 0x00000000 }, - { 0x419864, 1, 0x04, 0x00000129 }, - { 0x419888, 1, 0x04, 0x00000000 }, +static const struct nvc0_graph_pack +nvf0_grctx_pack_gpc[] = { + { nvc0_grctx_init_gpc_unk_0 }, + { nvd9_grctx_init_prop_0 }, + { nvd9_grctx_init_gpc_unk_1 }, + { nvf0_grctx_init_setup_0 }, + { nvc0_grctx_init_zcull_0 }, + { nvd9_grctx_init_crstr_0 }, + { nve4_grctx_init_gpm_0 }, + { nvf0_grctx_init_gpc_unk_2 }, + { nvc0_grctx_init_gcc_0 }, + {} +}; + +static const struct nvc0_graph_init +nvf0_grctx_init_tex_0[] = { { 0x419a00, 1, 0x04, 0x000000f0 }, { 0x419a04, 1, 0x04, 0x00000001 }, { 0x419a08, 1, 0x04, 0x00000021 }, @@ -169,14 +730,29 @@ nvf0_grctx_init_tpc[] = { { 0x419a20, 1, 0x04, 0x00020800 }, { 0x419a30, 1, 0x04, 0x00000001 }, { 0x419ac4, 1, 0x04, 0x0037f440 }, + {} +}; + +const struct nvc0_graph_init +nvf0_grctx_init_mpc_0[] = { { 0x419c00, 1, 0x04, 0x0000001a }, { 0x419c04, 1, 0x04, 0x80000006 }, { 0x419c08, 1, 0x04, 0x00000002 }, { 0x419c20, 1, 0x04, 0x00000000 }, { 0x419c24, 1, 0x04, 0x00084210 }, { 0x419c28, 1, 0x04, 0x3efbefbe }, + {} +}; + +const struct nvc0_graph_init +nvf0_grctx_init_l1c_0[] = { { 0x419ce8, 1, 0x04, 0x00000000 }, { 0x419cf4, 1, 0x04, 0x00000203 }, + {} +}; + +static const struct nvc0_graph_init +nvf0_grctx_init_sm_0[] = { { 0x419e04, 1, 0x04, 0x00000000 }, { 0x419e08, 1, 0x04, 0x0000001d }, { 0x419e0c, 1, 0x04, 0x00000000 }, @@ -189,8 +765,8 @@ nvf0_grctx_init_tpc[] = { { 0x419e5c, 3, 0x04, 0x00000000 }, { 0x419e68, 1, 0x04, 0x00000002 }, { 0x419e6c, 12, 0x04, 0x00000000 }, - { 0x419eac, 1, 0x04, 0x00001fcf }, - { 0x419eb0, 1, 0x04, 0x0db00da0 }, + { 0x419eac, 1, 0x04, 0x00001f8f }, + { 0x419eb0, 1, 0x04, 0x0db00d2f }, { 0x419eb8, 1, 0x04, 0x00000000 }, { 0x419ec8, 1, 0x04, 0x0001304f }, { 0x419f30, 4, 0x04, 0x00000000 }, @@ -203,24 +779,36 @@ nvf0_grctx_init_tpc[] = { {} }; -static struct nvc0_graph_init -nvf0_grctx_init_unk[] = { - { 0x41be24, 1, 0x04, 0x00000006 }, +static const struct nvc0_graph_pack +nvf0_grctx_pack_tpc[] = { + { nvd7_grctx_init_pe_0 }, + { nvf0_grctx_init_tex_0 }, + { nvf0_grctx_init_mpc_0 }, + { nvf0_grctx_init_l1c_0 }, + { nvf0_grctx_init_sm_0 }, + {} +}; + +static const struct nvc0_graph_init +nvf0_grctx_init_cbm_0[] = { { 0x41bec0, 1, 0x04, 0x10000000 }, { 0x41bec4, 1, 0x04, 0x00037f7f }, { 0x41bee4, 1, 0x04, 0x00000000 }, - { 0x41bf00, 1, 0x04, 0x0a418820 }, - { 0x41bf04, 1, 0x04, 0x062080e6 }, - { 0x41bf08, 1, 0x04, 0x020398a4 }, - { 0x41bf0c, 1, 0x04, 0x0e629062 }, - { 0x41bf10, 1, 0x04, 0x0a418820 }, - { 0x41bf14, 1, 0x04, 0x000000e6 }, - { 0x41bfd0, 1, 0x04, 0x00900103 }, - { 0x41bfe0, 1, 0x04, 0x00400001 }, - { 0x41bfe4, 1, 0x04, 0x00000000 }, {} }; +static const struct nvc0_graph_pack +nvf0_grctx_pack_ppc[] = { + { nve4_grctx_init_pes_0 }, + { nvf0_grctx_init_cbm_0 }, + { nvd7_grctx_init_wwdx_0 }, + {} +}; + +/******************************************************************************* + * PGRAPH context implementation + ******************************************************************************/ + static void nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) { @@ -254,7 +842,7 @@ nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) u16 magic3 = 0x0648; magic[gpc][0] = 0x10000000 | (magic0 << 16) | offset; magic[gpc][1] = 0x00000000 | (magic1 << 16); - offset += 0x0324 * (priv->tpc_nr[gpc] - 1);; + offset += 0x0324 * (priv->tpc_nr[gpc] - 1); magic[gpc][2] = 0x10000000 | (magic2 << 16) | offset; magic[gpc][3] = 0x00000000 | (magic3 << 16); offset += 0x0324; @@ -273,39 +861,6 @@ nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) mmio_list(0x17e920, 0x00090a05, 0, 0); } -static struct nvc0_graph_init * -nvf0_grctx_init_hub[] = { - nvc0_grctx_init_base, - nvf0_grctx_init_unk40xx, - nvf0_grctx_init_unk44xx, - nve4_grctx_init_unk46xx, - nve4_grctx_init_unk47xx, - nve4_grctx_init_unk58xx, - nvf0_grctx_init_unk5bxx, - nvf0_grctx_init_unk60xx, - nvf0_grctx_init_unk64xx, - nve4_grctx_init_unk80xx, - nvf0_grctx_init_unk88xx, - NULL -}; - -struct nvc0_graph_init * -nvf0_grctx_init_gpc[] = { - nvf0_grctx_init_gpc_0, - nvc0_grctx_init_gpc_1, - nvf0_grctx_init_tpc, - nvf0_grctx_init_unk, - NULL -}; - -static struct nvc0_graph_mthd -nvf0_grctx_init_mthd[] = { - { 0xa197, nvc1_grctx_init_9097, }, - { 0x902d, nvc0_grctx_init_902d, }, - { 0x902d, nvc0_grctx_init_mthd_magic, }, - {} -}; - struct nouveau_oclass * nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) { .base.handle = NV_ENGCTX(GR, 0xf0), @@ -317,11 +872,14 @@ nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) { .rd32 = _nouveau_graph_context_rd32, .wr32 = _nouveau_graph_context_wr32, }, - .main = nve4_grctx_generate_main, - .mods = nvf0_grctx_generate_mods, - .unkn = nve4_grctx_generate_unkn, - .hub = nvf0_grctx_init_hub, - .gpc = nvf0_grctx_init_gpc, - .icmd = nvc0_grctx_init_icmd, - .mthd = nvf0_grctx_init_mthd, + .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, + .zcull = nvc0_grctx_pack_zcull, + .tpc = nvf0_grctx_pack_tpc, + .ppc = nvf0_grctx_pack_ppc, + .icmd = nvf0_grctx_pack_icmd, + .mthd = nvf0_grctx_pack_mthd, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc index e148961b807..e37d8106ae1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc @@ -228,7 +228,7 @@ mmctx_xfer: and $r11 0x1f cmpu b32 $r11 0x10 bra ne #mmctx_fini_wait - mov $r10 2 // DONE_MMCTX + mov $r10 5 // DONE_MMCTX call(wait_donez) bra #mmctx_done mmctx_stop: diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc index 96cbcea3b2c..7445f12b1d9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc @@ -54,7 +54,7 @@ mmio_list_base: #ifdef INCLUDE_CODE // reports an exception to the host // -// In: $r15 error code (see nvc0.fuc) +// In: $r15 error code (see os.h) // error: push $r14 @@ -78,7 +78,12 @@ error: // init: clear b32 $r0 - mov $sp $r0 + + // setup stack + nv_iord($r1, NV_PGRAPH_GPCX_GPCCS_CAPS, 0) + extr $r1 $r1 9:17 + shl b32 $r1 8 + mov $sp $r1 // enable fifo access mov $r2 NV_PGRAPH_GPCX_GPCCS_ACCESS_FIFO diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5 b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5 new file mode 100644 index 00000000000..e730603891d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5 @@ -0,0 +1,42 @@ +/* + * 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> + */ + +#define NV_PGRAPH_GPCX_UNK__SIZE 0x00000002 + +#define CHIPSET GK208 +#include "macros.fuc" + +.section #gm107_grgpc_data +#define INCLUDE_DATA +#include "com.fuc" +#include "gpc.fuc" +#undef INCLUDE_DATA + +.section #gm107_grgpc_code +#define INCLUDE_CODE +bra #init +#include "com.fuc" +#include "gpc.fuc" +.align 256 +#undef INCLUDE_CODE diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h new file mode 100644 index 00000000000..6d53b67dd3c --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h @@ -0,0 +1,473 @@ +uint32_t gm107_grgpc_data[] = { +/* 0x0000: gpc_mmio_list_head */ + 0x0000006c, +/* 0x0004: gpc_mmio_list_tail */ +/* 0x0004: tpc_mmio_list_head */ + 0x0000006c, +/* 0x0008: tpc_mmio_list_tail */ +/* 0x0008: unk_mmio_list_head */ + 0x0000006c, +/* 0x000c: unk_mmio_list_tail */ + 0x0000006c, +/* 0x0010: gpc_id */ + 0x00000000, +/* 0x0014: tpc_count */ + 0x00000000, +/* 0x0018: tpc_mask */ + 0x00000000, +/* 0x001c: unk_count */ + 0x00000000, +/* 0x0020: unk_mask */ + 0x00000000, +/* 0x0024: cmd_queue */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; + +uint32_t gm107_grgpc_code[] = { + 0x03140ef5, +/* 0x0004: queue_put */ + 0x9800d898, + 0x86f001d9, + 0xf489a408, + 0x020f0b1b, + 0x0002f87e, +/* 0x001a: queue_put_next */ + 0x98c400f8, + 0x0384b607, + 0xb6008dbb, + 0x8eb50880, + 0x018fb500, + 0xf00190b6, + 0xd9b50f94, +/* 0x0037: queue_get */ + 0xf400f801, + 0xd8980131, + 0x01d99800, + 0x0bf489a4, + 0x0789c421, + 0xbb0394b6, + 0x90b6009d, + 0x009e9808, + 0xb6019f98, + 0x84f00180, + 0x00d8b50f, +/* 0x0063: queue_get_done */ + 0xf80132f4, +/* 0x0065: nv_rd32 */ + 0xf0ecb200, + 0x00801fc9, + 0x0cf601ca, +/* 0x0073: nv_rd32_wait */ + 0x8c04bd00, + 0xcf01ca00, + 0xccc800cc, + 0xf61bf41f, + 0xec7e060a, + 0x008f0000, + 0xffcf01cb, +/* 0x008f: nv_wr32 */ + 0x8000f800, + 0xf601cc00, + 0x04bd000f, + 0xc9f0ecb2, + 0x1ec9f01f, + 0x01ca0080, + 0xbd000cf6, +/* 0x00a9: nv_wr32_wait */ + 0xca008c04, + 0x00cccf01, + 0xf41fccc8, + 0x00f8f61b, +/* 0x00b8: wait_donez */ + 0x99f094bd, + 0x37008000, + 0x0009f602, + 0x008004bd, + 0x0af60206, +/* 0x00cf: wait_donez_ne */ + 0x8804bd00, + 0xcf010000, + 0x8aff0088, + 0xf61bf488, + 0x99f094bd, + 0x17008000, + 0x0009f602, + 0x00f804bd, +/* 0x00ec: wait_doneo */ + 0x99f094bd, + 0x37008000, + 0x0009f602, + 0x008004bd, + 0x0af60206, +/* 0x0103: wait_doneo_e */ + 0x8804bd00, + 0xcf010000, + 0x8aff0088, + 0xf60bf488, + 0x99f094bd, + 0x17008000, + 0x0009f602, + 0x00f804bd, +/* 0x0120: mmctx_size */ +/* 0x0122: nv_mmctx_size_loop */ + 0xe89894bd, + 0x1a85b600, + 0xb60180b6, + 0x98bb0284, + 0x04e0b600, + 0x1bf4efa4, + 0xf89fb2ec, +/* 0x013d: mmctx_xfer */ + 0xf094bd00, + 0x00800199, + 0x09f60237, + 0xbd04bd00, + 0x05bbfd94, + 0x800f0bf4, + 0xf601c400, + 0x04bd000b, +/* 0x015f: mmctx_base_disabled */ + 0xfd0099f0, + 0x0bf405ee, + 0xc6008018, + 0x000ef601, + 0x008004bd, + 0x0ff601c7, + 0xf004bd00, +/* 0x017a: mmctx_multi_disabled */ + 0xabc80199, + 0x10b4b600, + 0xc80cb9f0, + 0xe4b601ae, + 0x05befd11, + 0x01c50080, + 0xbd000bf6, +/* 0x0195: mmctx_exec_loop */ +/* 0x0195: mmctx_wait_free */ + 0xc5008e04, + 0x00eecf01, + 0xf41fe4f0, + 0xce98f60b, + 0x05e9fd00, + 0x01c80080, + 0xbd000ef6, + 0x04c0b604, + 0x1bf4cda4, + 0x02abc8df, +/* 0x01bf: mmctx_fini_wait */ + 0x8b1c1bf4, + 0xcf01c500, + 0xb4f000bb, + 0x10b4b01f, + 0x0af31bf4, + 0x00b87e05, + 0x250ef400, +/* 0x01d8: mmctx_stop */ + 0xb600abc8, + 0xb9f010b4, + 0x12b9f00c, + 0x01c50080, + 0xbd000bf6, +/* 0x01ed: mmctx_stop_wait */ + 0xc5008b04, + 0x00bbcf01, + 0xf412bbc8, +/* 0x01fa: mmctx_done */ + 0x94bdf61b, + 0x800199f0, + 0xf6021700, + 0x04bd0009, +/* 0x020a: strand_wait */ + 0xa0f900f8, + 0xb87e020a, + 0xa0fc0000, +/* 0x0216: strand_pre */ + 0x0c0900f8, + 0x024afc80, + 0xbd0009f6, + 0x020a7e04, +/* 0x0227: strand_post */ + 0x0900f800, + 0x4afc800d, + 0x0009f602, + 0x0a7e04bd, + 0x00f80002, +/* 0x0238: strand_set */ + 0xfc800f0c, + 0x0cf6024f, + 0x0c04bd00, + 0x4afc800b, + 0x000cf602, + 0xfc8004bd, + 0x0ef6024f, + 0x0c04bd00, + 0x4afc800a, + 0x000cf602, + 0x0a7e04bd, + 0x00f80002, +/* 0x0268: strand_ctx_init */ + 0x99f094bd, + 0x37008003, + 0x0009f602, + 0x167e04bd, + 0x030e0002, + 0x0002387e, + 0xfc80c4bd, + 0x0cf60247, + 0x0c04bd00, + 0x4afc8001, + 0x000cf602, + 0x0a7e04bd, + 0x0c920002, + 0x46fc8001, + 0x000cf602, + 0x020c04bd, + 0x024afc80, + 0xbd000cf6, + 0x020a7e04, + 0x02277e00, + 0x42008800, + 0x20008902, + 0x0099cf02, +/* 0x02c7: ctx_init_strand_loop */ + 0xf608fe95, + 0x8ef6008e, + 0x808acf40, + 0xb606a5b6, + 0xeabb01a0, + 0x0480b600, + 0xf40192b6, + 0xe4b6e81b, + 0xf2efbc08, + 0x99f094bd, + 0x17008003, + 0x0009f602, + 0x00f804bd, +/* 0x02f8: error */ + 0xffb2e0f9, + 0x4098148e, + 0x00008f7e, + 0xffb2010f, + 0x409c1c8e, + 0x00008f7e, + 0x00f8e0fc, +/* 0x0314: init */ + 0x004104bd, + 0x0011cf42, + 0x010911e7, + 0xfe0814b6, + 0x02020014, + 0xf6120040, + 0x04bd0002, + 0xfe047241, + 0x00400010, + 0x0000f607, + 0x040204bd, + 0xf6040040, + 0x04bd0002, + 0x821031f4, + 0xcf018200, + 0x01030022, + 0xbb1f24f0, + 0x32b60432, + 0x0502b501, + 0x820603b5, + 0xcf018600, + 0x02b50022, + 0x0c308e04, + 0xbd24bd50, +/* 0x0377: init_unk_loop */ + 0x7e44bd34, + 0xb0000065, + 0x0bf400f6, + 0xbb010f0e, + 0x4ffd04f2, + 0x0130b605, +/* 0x038c: init_unk_next */ + 0xb60120b6, + 0x26b004e0, + 0xe21bf402, +/* 0x0398: init_unk_done */ + 0xb50703b5, + 0x00820804, + 0x22cf0201, + 0x9534bd00, + 0x00800825, + 0x05f601c0, + 0x8004bd00, + 0xf601c100, + 0x04bd0005, + 0x98000e98, + 0x207e010f, + 0x2fbb0001, + 0x003fbb00, + 0x98010e98, + 0x207e020f, + 0x0e980001, + 0x00effd05, + 0xbb002ebb, + 0x0e98003e, + 0x030f9802, + 0x0001207e, + 0xfd070e98, + 0x2ebb00ef, + 0x003ebb00, + 0x800235b6, + 0xf601d300, + 0x04bd0003, + 0xb60825b6, + 0x20b60635, + 0x0130b601, + 0xb60824b6, + 0x2fb20834, + 0x0002687e, + 0x80003fbb, + 0xf6020100, + 0x04bd0003, + 0x29f024bd, + 0x3000801f, + 0x0002f602, +/* 0x0436: main */ + 0x31f404bd, + 0x0028f400, + 0x377e240d, + 0x01f40000, + 0x04e4b0f4, + 0xfe1d18f4, + 0x06020181, + 0x12fd20bd, + 0x01e4b604, + 0xfe051efd, + 0x097e0018, + 0x0ef40005, +/* 0x0465: main_not_ctx_xfer */ + 0x10ef94d4, + 0x7e01f5f0, + 0xf40002f8, +/* 0x0472: ih */ + 0x80f9c70e, + 0xf90188fe, + 0xf990f980, + 0xf9b0f9a0, + 0xf9e0f9d0, + 0x4a04bdf0, + 0xaacf0200, + 0x04abc400, + 0x0d1f0bf4, + 0x1a004e24, + 0x4f00eecf, + 0xffcf1900, + 0x00047e00, + 0x40010e00, + 0x0ef61d00, +/* 0x04af: ih_no_fifo */ + 0x4004bd00, + 0x0af60100, + 0xfc04bd00, + 0xfce0fcf0, + 0xfcb0fcd0, + 0xfc90fca0, + 0x0088fe80, + 0x32f480fc, +/* 0x04cf: hub_barrier_done */ + 0x0f01f800, + 0x040e9801, + 0xb204febb, + 0x94188eff, + 0x008f7e40, +/* 0x04e3: ctx_redswitch */ + 0x0f00f800, + 0x85008020, + 0x000ff601, + 0x080e04bd, +/* 0x04f0: ctx_redswitch_delay */ + 0xf401e2b6, + 0xf5f1fd1b, + 0xf5f10800, + 0x00800200, + 0x0ff60185, + 0xf804bd00, +/* 0x0509: ctx_xfer */ + 0x81008000, + 0x000ff602, + 0x11f404bd, + 0x04e37e07, +/* 0x0519: ctx_xfer_not_load */ + 0x02167e00, + 0x8024bd00, + 0xf60247fc, + 0x04bd0002, + 0xb6012cf0, + 0xfc800320, + 0x02f6024a, + 0xf004bd00, + 0xa5f001ac, + 0x00008b02, + 0x040c9850, + 0xbb0fc4b6, + 0x0c9800bc, + 0x010d9800, + 0x3d7e000e, + 0xacf00001, + 0x40008b01, + 0x040c9850, + 0xbb0fc4b6, + 0x0c9800bc, + 0x020d9801, + 0x4e060f98, + 0x3d7e0800, + 0xacf00001, + 0x04a5f001, + 0x5030008b, + 0xb6040c98, + 0xbcbb0fc4, + 0x020c9800, + 0x98030d98, + 0x004e080f, + 0x013d7e02, + 0x020a7e00, + 0x0601f400, +/* 0x05a3: ctx_xfer_post */ + 0x7e0712f4, +/* 0x05a7: ctx_xfer_done */ + 0x7e000227, + 0xf80004cf, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h index 27dc1280dc1..31922707794 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h @@ -177,7 +177,7 @@ uint32_t nv108_grgpc_code[] = { 0xb4f000bb, 0x10b4b01f, 0x0af31bf4, - 0x00b87e02, + 0x00b87e05, 0x250ef400, /* 0x01d8: mmctx_stop */ 0xb600abc8, @@ -269,186 +269,186 @@ uint32_t nv108_grgpc_code[] = { 0x00008f7e, 0x00f8e0fc, /* 0x0314: init */ - 0x04fe04bd, - 0x40020200, - 0x02f61200, - 0x4104bd00, - 0x10fe0465, - 0x07004000, - 0xbd0000f6, - 0x40040204, - 0x02f60400, - 0xf404bd00, - 0x00821031, - 0x22cf0182, - 0xf0010300, - 0x32bb1f24, - 0x0132b604, - 0xb50502b5, - 0x00820603, - 0x22cf0186, - 0x0402b500, - 0x500c308e, - 0x34bd24bd, -/* 0x036a: init_unk_loop */ - 0x657e44bd, - 0xf6b00000, - 0x0e0bf400, - 0xf2bb010f, - 0x054ffd04, -/* 0x037f: init_unk_next */ - 0xb60130b6, - 0xe0b60120, - 0x0126b004, -/* 0x038b: init_unk_done */ - 0xb5e21bf4, - 0x04b50703, - 0x01008208, - 0x0022cf02, - 0x259534bd, - 0xc0008008, - 0x0005f601, - 0x008004bd, - 0x05f601c1, - 0x9804bd00, - 0x0f98000e, - 0x01207e01, - 0x002fbb00, - 0x98003fbb, - 0x0f98010e, - 0x01207e02, - 0x050e9800, - 0xbb00effd, - 0x3ebb002e, - 0x020e9800, - 0x7e030f98, - 0x98000120, - 0xeffd070e, - 0x002ebb00, - 0xb6003ebb, - 0x00800235, - 0x03f601d3, - 0xb604bd00, - 0x35b60825, - 0x0120b606, - 0xb60130b6, - 0x34b60824, - 0x7e2fb208, - 0xbb000268, - 0x0080003f, - 0x03f60201, - 0xbd04bd00, - 0x1f29f024, - 0x02300080, - 0xbd0002f6, -/* 0x0429: main */ - 0x0031f404, - 0x0d0028f4, - 0x00377e24, - 0xf401f400, - 0xf404e4b0, - 0x81fe1d18, - 0xbd060201, - 0x0412fd20, - 0xfd01e4b6, - 0x18fe051e, - 0x04fc7e00, - 0xd40ef400, -/* 0x0458: main_not_ctx_xfer */ - 0xf010ef94, - 0xf87e01f5, - 0x0ef40002, -/* 0x0465: ih */ - 0xfe80f9c7, - 0x80f90188, - 0xa0f990f9, - 0xd0f9b0f9, - 0xf0f9e0f9, - 0x004a04bd, - 0x00aacf02, - 0xf404abc4, - 0x240d1f0b, - 0xcf1a004e, - 0x004f00ee, - 0x00ffcf19, - 0x0000047e, - 0x0040010e, - 0x000ef61d, -/* 0x04a2: ih_no_fifo */ - 0x004004bd, - 0x000af601, - 0xf0fc04bd, - 0xd0fce0fc, - 0xa0fcb0fc, - 0x80fc90fc, - 0xfc0088fe, - 0x0032f480, -/* 0x04c2: hub_barrier_done */ - 0x010f01f8, - 0xbb040e98, - 0xffb204fe, - 0x4094188e, - 0x00008f7e, -/* 0x04d6: ctx_redswitch */ - 0x200f00f8, - 0x01850080, - 0xbd000ff6, -/* 0x04e3: ctx_redswitch_delay */ - 0xb6080e04, - 0x1bf401e2, - 0x00f5f1fd, - 0x00f5f108, - 0x85008002, + 0x004104bd, + 0x0011cf42, + 0x010911e7, + 0xfe0814b6, + 0x02020014, + 0xf6120040, + 0x04bd0002, + 0xfe047241, + 0x00400010, + 0x0000f607, + 0x040204bd, + 0xf6040040, + 0x04bd0002, + 0x821031f4, + 0xcf018200, + 0x01030022, + 0xbb1f24f0, + 0x32b60432, + 0x0502b501, + 0x820603b5, + 0xcf018600, + 0x02b50022, + 0x0c308e04, + 0xbd24bd50, +/* 0x0377: init_unk_loop */ + 0x7e44bd34, + 0xb0000065, + 0x0bf400f6, + 0xbb010f0e, + 0x4ffd04f2, + 0x0130b605, +/* 0x038c: init_unk_next */ + 0xb60120b6, + 0x26b004e0, + 0xe21bf401, +/* 0x0398: init_unk_done */ + 0xb50703b5, + 0x00820804, + 0x22cf0201, + 0x9534bd00, + 0x00800825, + 0x05f601c0, + 0x8004bd00, + 0xf601c100, + 0x04bd0005, + 0x98000e98, + 0x207e010f, + 0x2fbb0001, + 0x003fbb00, + 0x98010e98, + 0x207e020f, + 0x0e980001, + 0x00effd05, + 0xbb002ebb, + 0x0e98003e, + 0x030f9802, + 0x0001207e, + 0xfd070e98, + 0x2ebb00ef, + 0x003ebb00, + 0x800235b6, + 0xf601d300, + 0x04bd0003, + 0xb60825b6, + 0x20b60635, + 0x0130b601, + 0xb60824b6, + 0x2fb20834, + 0x0002687e, + 0x80003fbb, + 0xf6020100, + 0x04bd0003, + 0x29f024bd, + 0x3000801f, + 0x0002f602, +/* 0x0436: main */ + 0x31f404bd, + 0x0028f400, + 0x377e240d, + 0x01f40000, + 0x04e4b0f4, + 0xfe1d18f4, + 0x06020181, + 0x12fd20bd, + 0x01e4b604, + 0xfe051efd, + 0x097e0018, + 0x0ef40005, +/* 0x0465: main_not_ctx_xfer */ + 0x10ef94d4, + 0x7e01f5f0, + 0xf40002f8, +/* 0x0472: ih */ + 0x80f9c70e, + 0xf90188fe, + 0xf990f980, + 0xf9b0f9a0, + 0xf9e0f9d0, + 0x4a04bdf0, + 0xaacf0200, + 0x04abc400, + 0x0d1f0bf4, + 0x1a004e24, + 0x4f00eecf, + 0xffcf1900, + 0x00047e00, + 0x40010e00, + 0x0ef61d00, +/* 0x04af: ih_no_fifo */ + 0x4004bd00, + 0x0af60100, + 0xfc04bd00, + 0xfce0fcf0, + 0xfcb0fcd0, + 0xfc90fca0, + 0x0088fe80, + 0x32f480fc, +/* 0x04cf: hub_barrier_done */ + 0x0f01f800, + 0x040e9801, + 0xb204febb, + 0x94188eff, + 0x008f7e40, +/* 0x04e3: ctx_redswitch */ + 0x0f00f800, + 0x85008020, 0x000ff601, - 0x00f804bd, -/* 0x04fc: ctx_xfer */ - 0x02810080, - 0xbd000ff6, - 0x0711f404, - 0x0004d67e, -/* 0x050c: ctx_xfer_not_load */ - 0x0002167e, - 0xfc8024bd, - 0x02f60247, + 0x080e04bd, +/* 0x04f0: ctx_redswitch_delay */ + 0xf401e2b6, + 0xf5f1fd1b, + 0xf5f10800, + 0x00800200, + 0x0ff60185, + 0xf804bd00, +/* 0x0509: ctx_xfer */ + 0x81008000, + 0x000ff602, + 0x11f404bd, + 0x04e37e07, +/* 0x0519: ctx_xfer_not_load */ + 0x02167e00, + 0x8024bd00, + 0xf60247fc, + 0x04bd0002, + 0xb6012cf0, + 0xfc800320, + 0x02f6024a, 0xf004bd00, - 0x20b6012c, - 0x4afc8003, - 0x0002f602, - 0xacf004bd, - 0x02a5f001, - 0x5000008b, + 0xa5f001ac, + 0x00008b02, + 0x040c9850, + 0xbb0fc4b6, + 0x0c9800bc, + 0x010d9800, + 0x3d7e000e, + 0xacf00001, + 0x40008b01, + 0x040c9850, + 0xbb0fc4b6, + 0x0c9800bc, + 0x020d9801, + 0x4e060f98, + 0x3d7e0800, + 0xacf00001, + 0x04a5f001, + 0x5030008b, 0xb6040c98, 0xbcbb0fc4, - 0x000c9800, - 0x0e010d98, - 0x013d7e00, - 0x01acf000, - 0x5040008b, - 0xb6040c98, - 0xbcbb0fc4, - 0x010c9800, - 0x98020d98, - 0x004e060f, - 0x013d7e08, - 0x01acf000, - 0x8b04a5f0, - 0x98503000, - 0xc4b6040c, - 0x00bcbb0f, - 0x98020c98, - 0x0f98030d, - 0x02004e08, - 0x00013d7e, - 0x00020a7e, - 0xf40601f4, -/* 0x0596: ctx_xfer_post */ - 0x277e0712, -/* 0x059a: ctx_xfer_done */ - 0xc27e0002, - 0x00f80004, - 0x00000000, - 0x00000000, - 0x00000000, + 0x020c9800, + 0x98030d98, + 0x004e080f, + 0x013d7e02, + 0x020a7e00, + 0x0601f400, +/* 0x05a3: ctx_xfer_post */ + 0x7e0712f4, +/* 0x05a7: ctx_xfer_done */ + 0x7e000227, + 0xf80004cf, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h index 0e7b01efae8..325cc7b7b2f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h @@ -192,7 +192,7 @@ uint32_t nvc0_grgpc_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -300,182 +300,182 @@ uint32_t nvc0_grgpc_code[] = { 0x21f440e3, 0xf8e0fc9d, /* 0x03a1: init */ - 0xfe04bd00, - 0x27f00004, - 0x0007f102, - 0x0003f012, - 0xbd0002d0, - 0xd517f104, - 0x0010fe04, - 0x070007f1, + 0xf104bd00, + 0xf0420017, + 0x11cf0013, + 0x0911e700, + 0x0814b601, + 0xf00014fe, + 0x07f10227, + 0x03f01200, + 0x0002d000, + 0x17f104bd, + 0x10fe04e6, + 0x0007f100, + 0x0003f007, + 0xbd0000d0, + 0x0427f004, + 0x040007f1, 0xd00003f0, - 0x04bd0000, - 0xf10427f0, - 0xf0040007, - 0x02d00003, - 0xf404bd00, - 0x27f11031, - 0x23f08200, - 0x0022cf01, - 0xf00137f0, - 0x32bb1f24, - 0x0132b604, - 0x80050280, - 0x27f10603, - 0x23f08600, - 0x0022cf01, - 0xf1040280, - 0xf0010027, - 0x22cf0223, - 0x9534bd00, - 0x07f10825, - 0x03f0c000, - 0x0005d001, - 0x07f104bd, - 0x03f0c100, - 0x0005d001, - 0x0e9804bd, - 0x010f9800, - 0x015021f5, - 0xbb002fbb, - 0x0e98003f, - 0x020f9801, - 0x015021f5, - 0xfd050e98, - 0x2ebb00ef, - 0x003ebb00, - 0xf10235b6, - 0xf0d30007, - 0x03d00103, - 0xb604bd00, - 0x35b60825, - 0x0120b606, - 0xb60130b6, - 0x34b60824, - 0x022fb908, - 0x02d321f5, - 0xf1003fbb, - 0xf0010007, - 0x03d00203, - 0xbd04bd00, - 0x1f29f024, - 0x080007f1, - 0xd00203f0, 0x04bd0002, -/* 0x0498: main */ - 0xf40031f4, - 0xd7f00028, - 0x3921f41c, - 0xb0f401f4, - 0x18f404e4, - 0x0181fe1e, - 0xbd0627f0, - 0x0412fd20, - 0xfd01e4b6, - 0x18fe051e, - 0x8d21f500, - 0xd30ef405, -/* 0x04c8: main_not_ctx_xfer */ - 0xf010ef94, - 0x21f501f5, - 0x0ef4037e, -/* 0x04d5: ih */ - 0xfe80f9c6, - 0x80f90188, - 0xa0f990f9, - 0xd0f9b0f9, - 0xf0f9e0f9, - 0xa7f104bd, - 0xa3f00200, - 0x00aacf00, - 0xf404abc4, - 0xd7f02c0b, - 0x00e7f11c, - 0x00e3f01a, - 0xf100eecf, - 0xf01900f7, - 0xffcf00f3, - 0x0421f400, - 0xf101e7f0, - 0xf01d0007, - 0x0ed00003, -/* 0x0523: ih_no_fifo */ + 0xf11031f4, + 0xf0820027, + 0x22cf0123, + 0x0137f000, + 0xbb1f24f0, + 0x32b60432, + 0x05028001, + 0xf1060380, + 0xf0860027, + 0x22cf0123, + 0x04028000, + 0x010027f1, + 0xcf0223f0, + 0x34bd0022, + 0xf1082595, + 0xf0c00007, + 0x05d00103, 0xf104bd00, - 0xf0010007, - 0x0ad00003, - 0xfc04bd00, - 0xfce0fcf0, - 0xfcb0fcd0, - 0xfc90fca0, - 0x0088fe80, - 0x32f480fc, -/* 0x0547: hub_barrier_done */ - 0xf001f800, - 0x0e9801f7, - 0x04febb04, - 0xf102ffb9, - 0xf09418e7, - 0x21f440e3, -/* 0x055f: ctx_redswitch */ - 0xf000f89d, - 0x07f120f7, - 0x03f08500, - 0x000fd001, - 0xe7f004bd, -/* 0x0571: ctx_redswitch_delay */ - 0x01e2b608, - 0xf1fd1bf4, - 0xf10800f5, - 0xf10200f5, + 0xf0c10007, + 0x05d00103, + 0x9804bd00, + 0x0f98000e, + 0x5021f501, + 0x002fbb01, + 0x98003fbb, + 0x0f98010e, + 0x5021f502, + 0x050e9801, + 0xbb00effd, + 0x3ebb002e, + 0x0235b600, + 0xd30007f1, + 0xd00103f0, + 0x04bd0003, + 0xb60825b6, + 0x20b60635, + 0x0130b601, + 0xb60824b6, + 0x2fb90834, + 0xd321f502, + 0x003fbb02, + 0x010007f1, + 0xd00203f0, + 0x04bd0003, + 0x29f024bd, + 0x0007f11f, + 0x0203f008, + 0xbd0002d0, +/* 0x04a9: main */ + 0x0031f404, + 0xf00028f4, + 0x21f41cd7, + 0xf401f439, + 0xf404e4b0, + 0x81fe1e18, + 0x0627f001, + 0x12fd20bd, + 0x01e4b604, + 0xfe051efd, + 0x21f50018, + 0x0ef4059e, +/* 0x04d9: main_not_ctx_xfer */ + 0x10ef94d3, + 0xf501f5f0, + 0xf4037e21, +/* 0x04e6: ih */ + 0x80f9c60e, + 0xf90188fe, + 0xf990f980, + 0xf9b0f9a0, + 0xf9e0f9d0, + 0xf104bdf0, + 0xf00200a7, + 0xaacf00a3, + 0x04abc400, + 0xf02c0bf4, + 0xe7f11cd7, + 0xe3f01a00, + 0x00eecf00, + 0x1900f7f1, + 0xcf00f3f0, + 0x21f400ff, + 0x01e7f004, + 0x1d0007f1, + 0xd00003f0, + 0x04bd000e, +/* 0x0534: ih_no_fifo */ + 0x010007f1, + 0xd00003f0, + 0x04bd000a, + 0xe0fcf0fc, + 0xb0fcd0fc, + 0x90fca0fc, + 0x88fe80fc, + 0xf480fc00, + 0x01f80032, +/* 0x0558: hub_barrier_done */ + 0x9801f7f0, + 0xfebb040e, + 0x02ffb904, + 0x9418e7f1, + 0xf440e3f0, + 0x00f89d21, +/* 0x0570: ctx_redswitch */ + 0xf120f7f0, 0xf0850007, 0x0fd00103, - 0xf804bd00, -/* 0x058d: ctx_xfer */ - 0x0007f100, - 0x0203f081, - 0xbd000fd0, - 0x0711f404, - 0x055f21f5, -/* 0x05a0: ctx_xfer_not_load */ - 0x026a21f5, - 0x07f124bd, - 0x03f047fc, - 0x0002d002, - 0x2cf004bd, - 0x0320b601, - 0x4afc07f1, - 0xd00203f0, - 0x04bd0002, + 0xf004bd00, +/* 0x0582: ctx_redswitch_delay */ + 0xe2b608e7, + 0xfd1bf401, + 0x0800f5f1, + 0x0200f5f1, + 0x850007f1, + 0xd00103f0, + 0x04bd000f, +/* 0x059e: ctx_xfer */ + 0x07f100f8, + 0x03f08100, + 0x000fd002, + 0x11f404bd, + 0x7021f507, +/* 0x05b1: ctx_xfer_not_load */ + 0x6a21f505, + 0xf124bd02, + 0xf047fc07, + 0x02d00203, + 0xf004bd00, + 0x20b6012c, + 0xfc07f103, + 0x0203f04a, + 0xbd0002d0, + 0x01acf004, + 0xf102a5f0, + 0xf00000b7, + 0x0c9850b3, + 0x0fc4b604, + 0x9800bcbb, + 0x0d98000c, + 0x00e7f001, + 0x016f21f5, 0xf001acf0, - 0xb7f102a5, - 0xb3f00000, + 0xb7f104a5, + 0xb3f04000, 0x040c9850, 0xbb0fc4b6, 0x0c9800bc, - 0x010d9800, - 0xf500e7f0, - 0xf0016f21, - 0xa5f001ac, - 0x00b7f104, - 0x50b3f040, - 0xb6040c98, - 0xbcbb0fc4, - 0x010c9800, - 0x98020d98, - 0xe7f1060f, - 0x21f50800, - 0x21f5016f, - 0x01f4025e, - 0x0712f406, -/* 0x0618: ctx_xfer_post */ - 0x027f21f5, -/* 0x061c: ctx_xfer_done */ - 0x054721f5, - 0x000000f8, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, + 0x020d9801, + 0xf1060f98, + 0xf50800e7, + 0xf5016f21, + 0xf4025e21, + 0x12f40601, +/* 0x0629: ctx_xfer_post */ + 0x7f21f507, +/* 0x062d: ctx_xfer_done */ + 0x5821f502, + 0x0000f805, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h index 84dd32db28a..d1504a4059c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h @@ -196,7 +196,7 @@ uint32_t nvd7_grgpc_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -304,212 +304,212 @@ uint32_t nvd7_grgpc_code[] = { 0x21f440e3, 0xf8e0fc9d, /* 0x03a1: init */ - 0xfe04bd00, - 0x27f00004, - 0x0007f102, - 0x0003f012, - 0xbd0002d0, - 0x1f17f104, - 0x0010fe05, - 0x070007f1, + 0xf104bd00, + 0xf0420017, + 0x11cf0013, + 0x0911e700, + 0x0814b601, + 0xf00014fe, + 0x07f10227, + 0x03f01200, + 0x0002d000, + 0x17f104bd, + 0x10fe0530, + 0x0007f100, + 0x0003f007, + 0xbd0000d0, + 0x0427f004, + 0x040007f1, 0xd00003f0, - 0x04bd0000, - 0xf10427f0, - 0xf0040007, - 0x02d00003, + 0x04bd0002, + 0xf11031f4, + 0xf0820027, + 0x22cf0123, + 0x0137f000, + 0xbb1f24f0, + 0x32b60432, + 0x05028001, + 0xf1060380, + 0xf0860027, + 0x22cf0123, + 0x04028000, + 0x0c30e7f1, + 0xbd50e3f0, + 0xbd34bd24, +/* 0x0421: init_unk_loop */ + 0x6821f444, + 0xf400f6b0, + 0xf7f00f0b, + 0x04f2bb01, + 0xb6054ffd, +/* 0x0436: init_unk_next */ + 0x20b60130, + 0x04e0b601, + 0xf40126b0, +/* 0x0442: init_unk_done */ + 0x0380e21b, + 0x08048007, + 0x010027f1, + 0xcf0223f0, + 0x34bd0022, + 0xf1082595, + 0xf0c00007, + 0x05d00103, + 0xf104bd00, + 0xf0c10007, + 0x05d00103, + 0x9804bd00, + 0x0f98000e, + 0x5021f501, + 0x002fbb01, + 0x98003fbb, + 0x0f98010e, + 0x5021f502, + 0x050e9801, + 0xbb00effd, + 0x3ebb002e, + 0x020e9800, + 0xf5030f98, + 0x98015021, + 0xeffd070e, + 0x002ebb00, + 0xb6003ebb, + 0x07f10235, + 0x03f0d300, + 0x0003d001, + 0x25b604bd, + 0x0635b608, + 0xb60120b6, + 0x24b60130, + 0x0834b608, + 0xf5022fb9, + 0xbb02d321, + 0x07f1003f, + 0x03f00100, + 0x0003d002, + 0x24bd04bd, + 0xf11f29f0, + 0xf0080007, + 0x02d00203, +/* 0x04f3: main */ 0xf404bd00, - 0x27f11031, - 0x23f08200, - 0x0022cf01, - 0xf00137f0, - 0x32bb1f24, - 0x0132b604, - 0x80050280, - 0x27f10603, - 0x23f08600, - 0x0022cf01, - 0xf1040280, - 0xf00c30e7, - 0x24bd50e3, - 0x44bd34bd, -/* 0x0410: init_unk_loop */ - 0xb06821f4, - 0x0bf400f6, - 0x01f7f00f, - 0xfd04f2bb, - 0x30b6054f, -/* 0x0425: init_unk_next */ - 0x0120b601, - 0xb004e0b6, - 0x1bf40126, -/* 0x0431: init_unk_done */ - 0x070380e2, - 0xf1080480, - 0xf0010027, - 0x22cf0223, - 0x9534bd00, - 0x07f10825, - 0x03f0c000, - 0x0005d001, + 0x28f40031, + 0x24d7f000, + 0xf43921f4, + 0xe4b0f401, + 0x1e18f404, + 0xf00181fe, + 0x20bd0627, + 0xb60412fd, + 0x1efd01e4, + 0x0018fe05, + 0x05e821f5, +/* 0x0523: main_not_ctx_xfer */ + 0x94d30ef4, + 0xf5f010ef, + 0x7e21f501, + 0xc60ef403, +/* 0x0530: ih */ + 0x88fe80f9, + 0xf980f901, + 0xf9a0f990, + 0xf9d0f9b0, + 0xbdf0f9e0, + 0x00a7f104, + 0x00a3f002, + 0xc400aacf, + 0x0bf404ab, + 0x24d7f02c, + 0x1a00e7f1, + 0xcf00e3f0, + 0xf7f100ee, + 0xf3f01900, + 0x00ffcf00, + 0xf00421f4, + 0x07f101e7, + 0x03f01d00, + 0x000ed000, +/* 0x057e: ih_no_fifo */ 0x07f104bd, - 0x03f0c100, - 0x0005d001, - 0x0e9804bd, - 0x010f9800, - 0x015021f5, - 0xbb002fbb, - 0x0e98003f, - 0x020f9801, - 0x015021f5, - 0xfd050e98, - 0x2ebb00ef, - 0x003ebb00, - 0x98020e98, - 0x21f5030f, - 0x0e980150, - 0x00effd07, - 0xbb002ebb, - 0x35b6003e, - 0x0007f102, - 0x0103f0d3, - 0xbd0003d0, - 0x0825b604, - 0xb60635b6, - 0x30b60120, - 0x0824b601, - 0xb90834b6, - 0x21f5022f, - 0x3fbb02d3, - 0x0007f100, - 0x0203f001, - 0xbd0003d0, - 0xf024bd04, - 0x07f11f29, - 0x03f00800, - 0x0002d002, -/* 0x04e2: main */ - 0x31f404bd, - 0x0028f400, - 0xf424d7f0, - 0x01f43921, - 0x04e4b0f4, - 0xfe1e18f4, - 0x27f00181, - 0xfd20bd06, - 0xe4b60412, - 0x051efd01, - 0xf50018fe, - 0xf405d721, -/* 0x0512: main_not_ctx_xfer */ - 0xef94d30e, - 0x01f5f010, - 0x037e21f5, -/* 0x051f: ih */ - 0xf9c60ef4, - 0x0188fe80, - 0x90f980f9, - 0xb0f9a0f9, - 0xe0f9d0f9, - 0x04bdf0f9, - 0x0200a7f1, - 0xcf00a3f0, - 0xabc400aa, - 0x2c0bf404, - 0xf124d7f0, - 0xf01a00e7, - 0xeecf00e3, - 0x00f7f100, - 0x00f3f019, - 0xf400ffcf, - 0xe7f00421, - 0x0007f101, - 0x0003f01d, - 0xbd000ed0, -/* 0x056d: ih_no_fifo */ - 0x0007f104, - 0x0003f001, - 0xbd000ad0, - 0xfcf0fc04, - 0xfcd0fce0, - 0xfca0fcb0, - 0xfe80fc90, - 0x80fc0088, - 0xf80032f4, -/* 0x0591: hub_barrier_done */ - 0x01f7f001, - 0xbb040e98, - 0xffb904fe, - 0x18e7f102, - 0x40e3f094, - 0xf89d21f4, -/* 0x05a9: ctx_redswitch */ - 0x20f7f000, - 0x850007f1, - 0xd00103f0, - 0x04bd000f, -/* 0x05bb: ctx_redswitch_delay */ - 0xb608e7f0, - 0x1bf401e2, - 0x00f5f1fd, - 0x00f5f108, - 0x0007f102, + 0x03f00100, + 0x000ad000, + 0xf0fc04bd, + 0xd0fce0fc, + 0xa0fcb0fc, + 0x80fc90fc, + 0xfc0088fe, + 0x0032f480, +/* 0x05a2: hub_barrier_done */ + 0xf7f001f8, + 0x040e9801, + 0xb904febb, + 0xe7f102ff, + 0xe3f09418, + 0x9d21f440, +/* 0x05ba: ctx_redswitch */ + 0xf7f000f8, + 0x0007f120, 0x0103f085, 0xbd000fd0, -/* 0x05d7: ctx_xfer */ - 0xf100f804, - 0xf0810007, - 0x0fd00203, - 0xf404bd00, - 0x21f50711, -/* 0x05ea: ctx_xfer_not_load */ - 0x21f505a9, - 0x24bd026a, - 0x47fc07f1, + 0x08e7f004, +/* 0x05cc: ctx_redswitch_delay */ + 0xf401e2b6, + 0xf5f1fd1b, + 0xf5f10800, + 0x07f10200, + 0x03f08500, + 0x000fd001, + 0x00f804bd, +/* 0x05e8: ctx_xfer */ + 0x810007f1, 0xd00203f0, - 0x04bd0002, - 0xb6012cf0, - 0x07f10320, - 0x03f04afc, - 0x0002d002, - 0xacf004bd, - 0x02a5f001, - 0x0000b7f1, - 0x9850b3f0, - 0xc4b6040c, - 0x00bcbb0f, - 0x98000c98, - 0xe7f0010d, - 0x6f21f500, - 0x01acf001, - 0x4000b7f1, + 0x04bd000f, + 0xf50711f4, +/* 0x05fb: ctx_xfer_not_load */ + 0xf505ba21, + 0xbd026a21, + 0xfc07f124, + 0x0203f047, + 0xbd0002d0, + 0x012cf004, + 0xf10320b6, + 0xf04afc07, + 0x02d00203, + 0xf004bd00, + 0xa5f001ac, + 0x00b7f102, + 0x50b3f000, + 0xb6040c98, + 0xbcbb0fc4, + 0x000c9800, + 0xf0010d98, + 0x21f500e7, + 0xacf0016f, + 0x00b7f101, + 0x50b3f040, + 0xb6040c98, + 0xbcbb0fc4, + 0x010c9800, + 0x98020d98, + 0xe7f1060f, + 0x21f50800, + 0xacf0016f, + 0x04a5f001, + 0x3000b7f1, 0x9850b3f0, 0xc4b6040c, 0x00bcbb0f, - 0x98010c98, - 0x0f98020d, - 0x00e7f106, - 0x6f21f508, - 0x01acf001, - 0xf104a5f0, - 0xf03000b7, - 0x0c9850b3, - 0x0fc4b604, - 0x9800bcbb, - 0x0d98020c, - 0x080f9803, - 0x0200e7f1, - 0x016f21f5, - 0x025e21f5, - 0xf40601f4, -/* 0x0686: ctx_xfer_post */ - 0x21f50712, -/* 0x068a: ctx_xfer_done */ - 0x21f5027f, - 0x00f80591, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, + 0x98020c98, + 0x0f98030d, + 0x00e7f108, + 0x6f21f502, + 0x5e21f501, + 0x0601f402, +/* 0x0697: ctx_xfer_post */ + 0xf50712f4, +/* 0x069b: ctx_xfer_done */ + 0xf5027f21, + 0xf805a221, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h index b6da800ee9c..855b220378f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h @@ -196,7 +196,7 @@ uint32_t nve0_grgpc_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -304,212 +304,212 @@ uint32_t nve0_grgpc_code[] = { 0x21f440e3, 0xf8e0fc9d, /* 0x03a1: init */ - 0xfe04bd00, - 0x27f00004, - 0x0007f102, - 0x0003f012, - 0xbd0002d0, - 0x1f17f104, - 0x0010fe05, - 0x070007f1, + 0xf104bd00, + 0xf0420017, + 0x11cf0013, + 0x0911e700, + 0x0814b601, + 0xf00014fe, + 0x07f10227, + 0x03f01200, + 0x0002d000, + 0x17f104bd, + 0x10fe0530, + 0x0007f100, + 0x0003f007, + 0xbd0000d0, + 0x0427f004, + 0x040007f1, 0xd00003f0, - 0x04bd0000, - 0xf10427f0, - 0xf0040007, - 0x02d00003, + 0x04bd0002, + 0xf11031f4, + 0xf0820027, + 0x22cf0123, + 0x0137f000, + 0xbb1f24f0, + 0x32b60432, + 0x05028001, + 0xf1060380, + 0xf0860027, + 0x22cf0123, + 0x04028000, + 0x0c30e7f1, + 0xbd50e3f0, + 0xbd34bd24, +/* 0x0421: init_unk_loop */ + 0x6821f444, + 0xf400f6b0, + 0xf7f00f0b, + 0x04f2bb01, + 0xb6054ffd, +/* 0x0436: init_unk_next */ + 0x20b60130, + 0x04e0b601, + 0xf40126b0, +/* 0x0442: init_unk_done */ + 0x0380e21b, + 0x08048007, + 0x010027f1, + 0xcf0223f0, + 0x34bd0022, + 0xf1082595, + 0xf0c00007, + 0x05d00103, + 0xf104bd00, + 0xf0c10007, + 0x05d00103, + 0x9804bd00, + 0x0f98000e, + 0x5021f501, + 0x002fbb01, + 0x98003fbb, + 0x0f98010e, + 0x5021f502, + 0x050e9801, + 0xbb00effd, + 0x3ebb002e, + 0x020e9800, + 0xf5030f98, + 0x98015021, + 0xeffd070e, + 0x002ebb00, + 0xb6003ebb, + 0x07f10235, + 0x03f0d300, + 0x0003d001, + 0x25b604bd, + 0x0635b608, + 0xb60120b6, + 0x24b60130, + 0x0834b608, + 0xf5022fb9, + 0xbb02d321, + 0x07f1003f, + 0x03f00100, + 0x0003d002, + 0x24bd04bd, + 0xf11f29f0, + 0xf0080007, + 0x02d00203, +/* 0x04f3: main */ 0xf404bd00, - 0x27f11031, - 0x23f08200, - 0x0022cf01, - 0xf00137f0, - 0x32bb1f24, - 0x0132b604, - 0x80050280, - 0x27f10603, - 0x23f08600, - 0x0022cf01, - 0xf1040280, - 0xf00c30e7, - 0x24bd50e3, - 0x44bd34bd, -/* 0x0410: init_unk_loop */ - 0xb06821f4, - 0x0bf400f6, - 0x01f7f00f, - 0xfd04f2bb, - 0x30b6054f, -/* 0x0425: init_unk_next */ - 0x0120b601, - 0xb004e0b6, - 0x1bf40126, -/* 0x0431: init_unk_done */ - 0x070380e2, - 0xf1080480, - 0xf0010027, - 0x22cf0223, - 0x9534bd00, - 0x07f10825, - 0x03f0c000, - 0x0005d001, + 0x28f40031, + 0x24d7f000, + 0xf43921f4, + 0xe4b0f401, + 0x1e18f404, + 0xf00181fe, + 0x20bd0627, + 0xb60412fd, + 0x1efd01e4, + 0x0018fe05, + 0x05e821f5, +/* 0x0523: main_not_ctx_xfer */ + 0x94d30ef4, + 0xf5f010ef, + 0x7e21f501, + 0xc60ef403, +/* 0x0530: ih */ + 0x88fe80f9, + 0xf980f901, + 0xf9a0f990, + 0xf9d0f9b0, + 0xbdf0f9e0, + 0x00a7f104, + 0x00a3f002, + 0xc400aacf, + 0x0bf404ab, + 0x24d7f02c, + 0x1a00e7f1, + 0xcf00e3f0, + 0xf7f100ee, + 0xf3f01900, + 0x00ffcf00, + 0xf00421f4, + 0x07f101e7, + 0x03f01d00, + 0x000ed000, +/* 0x057e: ih_no_fifo */ 0x07f104bd, - 0x03f0c100, - 0x0005d001, - 0x0e9804bd, - 0x010f9800, - 0x015021f5, - 0xbb002fbb, - 0x0e98003f, - 0x020f9801, - 0x015021f5, - 0xfd050e98, - 0x2ebb00ef, - 0x003ebb00, - 0x98020e98, - 0x21f5030f, - 0x0e980150, - 0x00effd07, - 0xbb002ebb, - 0x35b6003e, - 0x0007f102, - 0x0103f0d3, - 0xbd0003d0, - 0x0825b604, - 0xb60635b6, - 0x30b60120, - 0x0824b601, - 0xb90834b6, - 0x21f5022f, - 0x3fbb02d3, - 0x0007f100, - 0x0203f001, - 0xbd0003d0, - 0xf024bd04, - 0x07f11f29, - 0x03f00800, - 0x0002d002, -/* 0x04e2: main */ - 0x31f404bd, - 0x0028f400, - 0xf424d7f0, - 0x01f43921, - 0x04e4b0f4, - 0xfe1e18f4, - 0x27f00181, - 0xfd20bd06, - 0xe4b60412, - 0x051efd01, - 0xf50018fe, - 0xf405d721, -/* 0x0512: main_not_ctx_xfer */ - 0xef94d30e, - 0x01f5f010, - 0x037e21f5, -/* 0x051f: ih */ - 0xf9c60ef4, - 0x0188fe80, - 0x90f980f9, - 0xb0f9a0f9, - 0xe0f9d0f9, - 0x04bdf0f9, - 0x0200a7f1, - 0xcf00a3f0, - 0xabc400aa, - 0x2c0bf404, - 0xf124d7f0, - 0xf01a00e7, - 0xeecf00e3, - 0x00f7f100, - 0x00f3f019, - 0xf400ffcf, - 0xe7f00421, - 0x0007f101, - 0x0003f01d, - 0xbd000ed0, -/* 0x056d: ih_no_fifo */ - 0x0007f104, - 0x0003f001, - 0xbd000ad0, - 0xfcf0fc04, - 0xfcd0fce0, - 0xfca0fcb0, - 0xfe80fc90, - 0x80fc0088, - 0xf80032f4, -/* 0x0591: hub_barrier_done */ - 0x01f7f001, - 0xbb040e98, - 0xffb904fe, - 0x18e7f102, - 0x40e3f094, - 0xf89d21f4, -/* 0x05a9: ctx_redswitch */ - 0x20f7f000, - 0x850007f1, - 0xd00103f0, - 0x04bd000f, -/* 0x05bb: ctx_redswitch_delay */ - 0xb608e7f0, - 0x1bf401e2, - 0x00f5f1fd, - 0x00f5f108, - 0x0007f102, + 0x03f00100, + 0x000ad000, + 0xf0fc04bd, + 0xd0fce0fc, + 0xa0fcb0fc, + 0x80fc90fc, + 0xfc0088fe, + 0x0032f480, +/* 0x05a2: hub_barrier_done */ + 0xf7f001f8, + 0x040e9801, + 0xb904febb, + 0xe7f102ff, + 0xe3f09418, + 0x9d21f440, +/* 0x05ba: ctx_redswitch */ + 0xf7f000f8, + 0x0007f120, 0x0103f085, 0xbd000fd0, -/* 0x05d7: ctx_xfer */ - 0xf100f804, - 0xf0810007, - 0x0fd00203, - 0xf404bd00, - 0x21f50711, -/* 0x05ea: ctx_xfer_not_load */ - 0x21f505a9, - 0x24bd026a, - 0x47fc07f1, + 0x08e7f004, +/* 0x05cc: ctx_redswitch_delay */ + 0xf401e2b6, + 0xf5f1fd1b, + 0xf5f10800, + 0x07f10200, + 0x03f08500, + 0x000fd001, + 0x00f804bd, +/* 0x05e8: ctx_xfer */ + 0x810007f1, 0xd00203f0, - 0x04bd0002, - 0xb6012cf0, - 0x07f10320, - 0x03f04afc, - 0x0002d002, - 0xacf004bd, - 0x02a5f001, - 0x0000b7f1, - 0x9850b3f0, - 0xc4b6040c, - 0x00bcbb0f, - 0x98000c98, - 0xe7f0010d, - 0x6f21f500, - 0x01acf001, - 0x4000b7f1, + 0x04bd000f, + 0xf50711f4, +/* 0x05fb: ctx_xfer_not_load */ + 0xf505ba21, + 0xbd026a21, + 0xfc07f124, + 0x0203f047, + 0xbd0002d0, + 0x012cf004, + 0xf10320b6, + 0xf04afc07, + 0x02d00203, + 0xf004bd00, + 0xa5f001ac, + 0x00b7f102, + 0x50b3f000, + 0xb6040c98, + 0xbcbb0fc4, + 0x000c9800, + 0xf0010d98, + 0x21f500e7, + 0xacf0016f, + 0x00b7f101, + 0x50b3f040, + 0xb6040c98, + 0xbcbb0fc4, + 0x010c9800, + 0x98020d98, + 0xe7f1060f, + 0x21f50800, + 0xacf0016f, + 0x04a5f001, + 0x3000b7f1, 0x9850b3f0, 0xc4b6040c, 0x00bcbb0f, - 0x98010c98, - 0x0f98020d, - 0x00e7f106, - 0x6f21f508, - 0x01acf001, - 0xf104a5f0, - 0xf03000b7, - 0x0c9850b3, - 0x0fc4b604, - 0x9800bcbb, - 0x0d98020c, - 0x080f9803, - 0x0200e7f1, - 0x016f21f5, - 0x025e21f5, - 0xf40601f4, -/* 0x0686: ctx_xfer_post */ - 0x21f50712, -/* 0x068a: ctx_xfer_done */ - 0x21f5027f, - 0x00f80591, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, + 0x98020c98, + 0x0f98030d, + 0x00e7f108, + 0x6f21f502, + 0x5e21f501, + 0x0601f402, +/* 0x0697: ctx_xfer_post */ + 0xf50712f4, +/* 0x069b: ctx_xfer_done */ + 0xf5027f21, + 0xf805a221, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h index 6316ebaf5d9..1b803197d28 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h @@ -196,7 +196,7 @@ uint32_t nvf0_grgpc_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -304,212 +304,212 @@ uint32_t nvf0_grgpc_code[] = { 0x21f440e3, 0xf8e0fc9d, /* 0x03a1: init */ - 0xfe04bd00, - 0x27f00004, - 0x0007f102, - 0x0003f012, - 0xbd0002d0, - 0x1f17f104, - 0x0010fe05, - 0x070007f1, + 0xf104bd00, + 0xf0420017, + 0x11cf0013, + 0x0911e700, + 0x0814b601, + 0xf00014fe, + 0x07f10227, + 0x03f01200, + 0x0002d000, + 0x17f104bd, + 0x10fe0530, + 0x0007f100, + 0x0003f007, + 0xbd0000d0, + 0x0427f004, + 0x040007f1, 0xd00003f0, - 0x04bd0000, - 0xf10427f0, - 0xf0040007, - 0x02d00003, + 0x04bd0002, + 0xf11031f4, + 0xf0820027, + 0x22cf0123, + 0x0137f000, + 0xbb1f24f0, + 0x32b60432, + 0x05028001, + 0xf1060380, + 0xf0860027, + 0x22cf0123, + 0x04028000, + 0x0c30e7f1, + 0xbd50e3f0, + 0xbd34bd24, +/* 0x0421: init_unk_loop */ + 0x6821f444, + 0xf400f6b0, + 0xf7f00f0b, + 0x04f2bb01, + 0xb6054ffd, +/* 0x0436: init_unk_next */ + 0x20b60130, + 0x04e0b601, + 0xf40226b0, +/* 0x0442: init_unk_done */ + 0x0380e21b, + 0x08048007, + 0x010027f1, + 0xcf0223f0, + 0x34bd0022, + 0xf1082595, + 0xf0c00007, + 0x05d00103, + 0xf104bd00, + 0xf0c10007, + 0x05d00103, + 0x9804bd00, + 0x0f98000e, + 0x5021f501, + 0x002fbb01, + 0x98003fbb, + 0x0f98010e, + 0x5021f502, + 0x050e9801, + 0xbb00effd, + 0x3ebb002e, + 0x020e9800, + 0xf5030f98, + 0x98015021, + 0xeffd070e, + 0x002ebb00, + 0xb6003ebb, + 0x07f10235, + 0x03f0d300, + 0x0003d001, + 0x25b604bd, + 0x0635b608, + 0xb60120b6, + 0x24b60130, + 0x0834b608, + 0xf5022fb9, + 0xbb02d321, + 0x07f1003f, + 0x03f00100, + 0x0003d002, + 0x24bd04bd, + 0xf11f29f0, + 0xf0300007, + 0x02d00203, +/* 0x04f3: main */ 0xf404bd00, - 0x27f11031, - 0x23f08200, - 0x0022cf01, - 0xf00137f0, - 0x32bb1f24, - 0x0132b604, - 0x80050280, - 0x27f10603, - 0x23f08600, - 0x0022cf01, - 0xf1040280, - 0xf00c30e7, - 0x24bd50e3, - 0x44bd34bd, -/* 0x0410: init_unk_loop */ - 0xb06821f4, - 0x0bf400f6, - 0x01f7f00f, - 0xfd04f2bb, - 0x30b6054f, -/* 0x0425: init_unk_next */ - 0x0120b601, - 0xb004e0b6, - 0x1bf40226, -/* 0x0431: init_unk_done */ - 0x070380e2, - 0xf1080480, - 0xf0010027, - 0x22cf0223, - 0x9534bd00, - 0x07f10825, - 0x03f0c000, - 0x0005d001, + 0x28f40031, + 0x24d7f000, + 0xf43921f4, + 0xe4b0f401, + 0x1e18f404, + 0xf00181fe, + 0x20bd0627, + 0xb60412fd, + 0x1efd01e4, + 0x0018fe05, + 0x05e821f5, +/* 0x0523: main_not_ctx_xfer */ + 0x94d30ef4, + 0xf5f010ef, + 0x7e21f501, + 0xc60ef403, +/* 0x0530: ih */ + 0x88fe80f9, + 0xf980f901, + 0xf9a0f990, + 0xf9d0f9b0, + 0xbdf0f9e0, + 0x00a7f104, + 0x00a3f002, + 0xc400aacf, + 0x0bf404ab, + 0x24d7f02c, + 0x1a00e7f1, + 0xcf00e3f0, + 0xf7f100ee, + 0xf3f01900, + 0x00ffcf00, + 0xf00421f4, + 0x07f101e7, + 0x03f01d00, + 0x000ed000, +/* 0x057e: ih_no_fifo */ 0x07f104bd, - 0x03f0c100, - 0x0005d001, - 0x0e9804bd, - 0x010f9800, - 0x015021f5, - 0xbb002fbb, - 0x0e98003f, - 0x020f9801, - 0x015021f5, - 0xfd050e98, - 0x2ebb00ef, - 0x003ebb00, - 0x98020e98, - 0x21f5030f, - 0x0e980150, - 0x00effd07, - 0xbb002ebb, - 0x35b6003e, - 0x0007f102, - 0x0103f0d3, - 0xbd0003d0, - 0x0825b604, - 0xb60635b6, - 0x30b60120, - 0x0824b601, - 0xb90834b6, - 0x21f5022f, - 0x3fbb02d3, - 0x0007f100, - 0x0203f001, - 0xbd0003d0, - 0xf024bd04, - 0x07f11f29, - 0x03f03000, - 0x0002d002, -/* 0x04e2: main */ - 0x31f404bd, - 0x0028f400, - 0xf424d7f0, - 0x01f43921, - 0x04e4b0f4, - 0xfe1e18f4, - 0x27f00181, - 0xfd20bd06, - 0xe4b60412, - 0x051efd01, - 0xf50018fe, - 0xf405d721, -/* 0x0512: main_not_ctx_xfer */ - 0xef94d30e, - 0x01f5f010, - 0x037e21f5, -/* 0x051f: ih */ - 0xf9c60ef4, - 0x0188fe80, - 0x90f980f9, - 0xb0f9a0f9, - 0xe0f9d0f9, - 0x04bdf0f9, - 0x0200a7f1, - 0xcf00a3f0, - 0xabc400aa, - 0x2c0bf404, - 0xf124d7f0, - 0xf01a00e7, - 0xeecf00e3, - 0x00f7f100, - 0x00f3f019, - 0xf400ffcf, - 0xe7f00421, - 0x0007f101, - 0x0003f01d, - 0xbd000ed0, -/* 0x056d: ih_no_fifo */ - 0x0007f104, - 0x0003f001, - 0xbd000ad0, - 0xfcf0fc04, - 0xfcd0fce0, - 0xfca0fcb0, - 0xfe80fc90, - 0x80fc0088, - 0xf80032f4, -/* 0x0591: hub_barrier_done */ - 0x01f7f001, - 0xbb040e98, - 0xffb904fe, - 0x18e7f102, - 0x40e3f094, - 0xf89d21f4, -/* 0x05a9: ctx_redswitch */ - 0x20f7f000, - 0x850007f1, - 0xd00103f0, - 0x04bd000f, -/* 0x05bb: ctx_redswitch_delay */ - 0xb608e7f0, - 0x1bf401e2, - 0x00f5f1fd, - 0x00f5f108, - 0x0007f102, + 0x03f00100, + 0x000ad000, + 0xf0fc04bd, + 0xd0fce0fc, + 0xa0fcb0fc, + 0x80fc90fc, + 0xfc0088fe, + 0x0032f480, +/* 0x05a2: hub_barrier_done */ + 0xf7f001f8, + 0x040e9801, + 0xb904febb, + 0xe7f102ff, + 0xe3f09418, + 0x9d21f440, +/* 0x05ba: ctx_redswitch */ + 0xf7f000f8, + 0x0007f120, 0x0103f085, 0xbd000fd0, -/* 0x05d7: ctx_xfer */ - 0xf100f804, - 0xf0810007, - 0x0fd00203, - 0xf404bd00, - 0x21f50711, -/* 0x05ea: ctx_xfer_not_load */ - 0x21f505a9, - 0x24bd026a, - 0x47fc07f1, + 0x08e7f004, +/* 0x05cc: ctx_redswitch_delay */ + 0xf401e2b6, + 0xf5f1fd1b, + 0xf5f10800, + 0x07f10200, + 0x03f08500, + 0x000fd001, + 0x00f804bd, +/* 0x05e8: ctx_xfer */ + 0x810007f1, 0xd00203f0, - 0x04bd0002, - 0xb6012cf0, - 0x07f10320, - 0x03f04afc, - 0x0002d002, - 0xacf004bd, - 0x02a5f001, - 0x0000b7f1, - 0x9850b3f0, - 0xc4b6040c, - 0x00bcbb0f, - 0x98000c98, - 0xe7f0010d, - 0x6f21f500, - 0x01acf001, - 0x4000b7f1, + 0x04bd000f, + 0xf50711f4, +/* 0x05fb: ctx_xfer_not_load */ + 0xf505ba21, + 0xbd026a21, + 0xfc07f124, + 0x0203f047, + 0xbd0002d0, + 0x012cf004, + 0xf10320b6, + 0xf04afc07, + 0x02d00203, + 0xf004bd00, + 0xa5f001ac, + 0x00b7f102, + 0x50b3f000, + 0xb6040c98, + 0xbcbb0fc4, + 0x000c9800, + 0xf0010d98, + 0x21f500e7, + 0xacf0016f, + 0x00b7f101, + 0x50b3f040, + 0xb6040c98, + 0xbcbb0fc4, + 0x010c9800, + 0x98020d98, + 0xe7f1060f, + 0x21f50800, + 0xacf0016f, + 0x04a5f001, + 0x3000b7f1, 0x9850b3f0, 0xc4b6040c, 0x00bcbb0f, - 0x98010c98, - 0x0f98020d, - 0x00e7f106, - 0x6f21f508, - 0x01acf001, - 0xf104a5f0, - 0xf03000b7, - 0x0c9850b3, - 0x0fc4b604, - 0x9800bcbb, - 0x0d98020c, - 0x080f9803, - 0x0200e7f1, - 0x016f21f5, - 0x025e21f5, - 0xf40601f4, -/* 0x0686: ctx_xfer_post */ - 0x21f50712, -/* 0x068a: ctx_xfer_done */ - 0x21f5027f, - 0x00f80591, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, + 0x98020c98, + 0x0f98030d, + 0x00e7f108, + 0x6f21f502, + 0x5e21f501, + 0x0601f402, +/* 0x0697: ctx_xfer_post */ + 0xf50712f4, +/* 0x069b: ctx_xfer_done */ + 0xf5027f21, + 0xf805a221, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc index c8ddb8d71b9..b4ad18bf5a2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc @@ -49,7 +49,7 @@ hub_mmio_list_next: #ifdef INCLUDE_CODE // reports an exception to the host // -// In: $r15 error code (see nvc0.fuc) +// In: $r15 error code (see os.h) // error: nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(5), 0, $r15) @@ -343,13 +343,25 @@ ih: ih_no_ctxsw: and $r11 $r10 NV_PGRAPH_FECS_INTR_FWMTHD bra e #ih_no_fwmthd - // none we handle, ack, and fall-through to unhandled + // none we handle; report to host and ack + nv_rd32($r15, NV_PGRAPH_TRAPPED_DATA_LO) + nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(4), 0, $r15) + nv_rd32($r15, NV_PGRAPH_TRAPPED_ADDR) + nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(3), 0, $r15) + extr $r14 $r15 16:18 + shl b32 $r14 $r14 2 + imm32($r15, NV_PGRAPH_FE_OBJECT_TABLE(0)) + add b32 $r14 $r15 + call(nv_rd32) + nv_iowr(NV_PGRAPH_FECS_CC_SCRATCH_VAL(2), 0, $r15) + mov $r15 E_BAD_FWMTHD + call(error) mov $r11 0x100 nv_wr32(0x400144, $r11) // anything we didn't handle, bring it to the host's attention ih_no_fwmthd: - mov $r11 0x104 // FIFO | CHSW + mov $r11 0x504 // FIFO | CHSW | FWMTHD not b32 $r11 and $r11 $r10 $r11 bra e #ih_no_other diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5 b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5 new file mode 100644 index 00000000000..27591b3086a --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5 @@ -0,0 +1,40 @@ +/* + * 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> + */ + +#define CHIPSET GK208 +#include "macros.fuc" + +.section #gm107_grhub_data +#define INCLUDE_DATA +#include "com.fuc" +#include "hub.fuc" +#undef INCLUDE_DATA + +.section #gm107_grhub_code +#define INCLUDE_CODE +bra #init +#include "com.fuc" +#include "hub.fuc" +.align 256 +#undef INCLUDE_CODE diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h new file mode 100644 index 00000000000..5f953c5c20b --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h @@ -0,0 +1,916 @@ +uint32_t gm107_grhub_data[] = { +/* 0x0000: hub_mmio_list_head */ + 0x00000300, +/* 0x0004: hub_mmio_list_tail */ + 0x00000304, +/* 0x0008: gpc_count */ + 0x00000000, +/* 0x000c: rop_count */ + 0x00000000, +/* 0x0010: cmd_queue */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0058: ctx_current */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0100: chan_data */ +/* 0x0100: chan_mmio_count */ + 0x00000000, +/* 0x0104: chan_mmio_address */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0200: xfer_data */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +/* 0x0300: hub_mmio_list_base */ + 0x0417e91c, +}; + +uint32_t gm107_grhub_code[] = { + 0x030e0ef5, +/* 0x0004: queue_put */ + 0x9800d898, + 0x86f001d9, + 0xf489a408, + 0x020f0b1b, + 0x0002f87e, +/* 0x001a: queue_put_next */ + 0x98c400f8, + 0x0384b607, + 0xb6008dbb, + 0x8eb50880, + 0x018fb500, + 0xf00190b6, + 0xd9b50f94, +/* 0x0037: queue_get */ + 0xf400f801, + 0xd8980131, + 0x01d99800, + 0x0bf489a4, + 0x0789c421, + 0xbb0394b6, + 0x90b6009d, + 0x009e9808, + 0xb6019f98, + 0x84f00180, + 0x00d8b50f, +/* 0x0063: queue_get_done */ + 0xf80132f4, +/* 0x0065: nv_rd32 */ + 0xf0ecb200, + 0x00801fc9, + 0x0cf601ca, +/* 0x0073: nv_rd32_wait */ + 0x8c04bd00, + 0xcf01ca00, + 0xccc800cc, + 0xf61bf41f, + 0xec7e060a, + 0x008f0000, + 0xffcf01cb, +/* 0x008f: nv_wr32 */ + 0x8000f800, + 0xf601cc00, + 0x04bd000f, + 0xc9f0ecb2, + 0x1ec9f01f, + 0x01ca0080, + 0xbd000cf6, +/* 0x00a9: nv_wr32_wait */ + 0xca008c04, + 0x00cccf01, + 0xf41fccc8, + 0x00f8f61b, +/* 0x00b8: wait_donez */ + 0x99f094bd, + 0x37008000, + 0x0009f602, + 0x008004bd, + 0x0af60206, +/* 0x00cf: wait_donez_ne */ + 0x8804bd00, + 0xcf010000, + 0x8aff0088, + 0xf61bf488, + 0x99f094bd, + 0x17008000, + 0x0009f602, + 0x00f804bd, +/* 0x00ec: wait_doneo */ + 0x99f094bd, + 0x37008000, + 0x0009f602, + 0x008004bd, + 0x0af60206, +/* 0x0103: wait_doneo_e */ + 0x8804bd00, + 0xcf010000, + 0x8aff0088, + 0xf60bf488, + 0x99f094bd, + 0x17008000, + 0x0009f602, + 0x00f804bd, +/* 0x0120: mmctx_size */ +/* 0x0122: nv_mmctx_size_loop */ + 0xe89894bd, + 0x1a85b600, + 0xb60180b6, + 0x98bb0284, + 0x04e0b600, + 0x1bf4efa4, + 0xf89fb2ec, +/* 0x013d: mmctx_xfer */ + 0xf094bd00, + 0x00800199, + 0x09f60237, + 0xbd04bd00, + 0x05bbfd94, + 0x800f0bf4, + 0xf601c400, + 0x04bd000b, +/* 0x015f: mmctx_base_disabled */ + 0xfd0099f0, + 0x0bf405ee, + 0xc6008018, + 0x000ef601, + 0x008004bd, + 0x0ff601c7, + 0xf004bd00, +/* 0x017a: mmctx_multi_disabled */ + 0xabc80199, + 0x10b4b600, + 0xc80cb9f0, + 0xe4b601ae, + 0x05befd11, + 0x01c50080, + 0xbd000bf6, +/* 0x0195: mmctx_exec_loop */ +/* 0x0195: mmctx_wait_free */ + 0xc5008e04, + 0x00eecf01, + 0xf41fe4f0, + 0xce98f60b, + 0x05e9fd00, + 0x01c80080, + 0xbd000ef6, + 0x04c0b604, + 0x1bf4cda4, + 0x02abc8df, +/* 0x01bf: mmctx_fini_wait */ + 0x8b1c1bf4, + 0xcf01c500, + 0xb4f000bb, + 0x10b4b01f, + 0x0af31bf4, + 0x00b87e05, + 0x250ef400, +/* 0x01d8: mmctx_stop */ + 0xb600abc8, + 0xb9f010b4, + 0x12b9f00c, + 0x01c50080, + 0xbd000bf6, +/* 0x01ed: mmctx_stop_wait */ + 0xc5008b04, + 0x00bbcf01, + 0xf412bbc8, +/* 0x01fa: mmctx_done */ + 0x94bdf61b, + 0x800199f0, + 0xf6021700, + 0x04bd0009, +/* 0x020a: strand_wait */ + 0xa0f900f8, + 0xb87e020a, + 0xa0fc0000, +/* 0x0216: strand_pre */ + 0x0c0900f8, + 0x024afc80, + 0xbd0009f6, + 0x020a7e04, +/* 0x0227: strand_post */ + 0x0900f800, + 0x4afc800d, + 0x0009f602, + 0x0a7e04bd, + 0x00f80002, +/* 0x0238: strand_set */ + 0xfc800f0c, + 0x0cf6024f, + 0x0c04bd00, + 0x4afc800b, + 0x000cf602, + 0xfc8004bd, + 0x0ef6024f, + 0x0c04bd00, + 0x4afc800a, + 0x000cf602, + 0x0a7e04bd, + 0x00f80002, +/* 0x0268: strand_ctx_init */ + 0x99f094bd, + 0x37008003, + 0x0009f602, + 0x167e04bd, + 0x030e0002, + 0x0002387e, + 0xfc80c4bd, + 0x0cf60247, + 0x0c04bd00, + 0x4afc8001, + 0x000cf602, + 0x0a7e04bd, + 0x0c920002, + 0x46fc8001, + 0x000cf602, + 0x020c04bd, + 0x024afc80, + 0xbd000cf6, + 0x020a7e04, + 0x02277e00, + 0x42008800, + 0x20008902, + 0x0099cf02, +/* 0x02c7: ctx_init_strand_loop */ + 0xf608fe95, + 0x8ef6008e, + 0x808acf40, + 0xb606a5b6, + 0xeabb01a0, + 0x0480b600, + 0xf40192b6, + 0xe4b6e81b, + 0xf2efbc08, + 0x99f094bd, + 0x17008003, + 0x0009f602, + 0x00f804bd, +/* 0x02f8: error */ + 0x02050080, + 0xbd000ff6, + 0x80010f04, + 0xf6030700, + 0x04bd000f, +/* 0x030e: init */ + 0x04bd00f8, + 0x410007fe, + 0x11cf4200, + 0x0911e700, + 0x0814b601, + 0x020014fe, + 0x12004002, + 0xbd0002f6, + 0x05c94104, + 0xbd0010fe, + 0x07004024, + 0xbd0002f6, + 0x20034204, + 0x01010080, + 0xbd0002f6, + 0x20044204, + 0x01010480, + 0xbd0002f6, + 0x200b4204, + 0x01010880, + 0xbd0002f6, + 0x200c4204, + 0x01011c80, + 0xbd0002f6, + 0x01039204, + 0x03090080, + 0xbd0003f6, + 0x87044204, + 0xf6040040, + 0x04bd0002, + 0x00400402, + 0x0002f603, + 0x31f404bd, + 0x96048e10, + 0x00657e40, + 0xc7feb200, + 0x01b590f1, + 0x1ff4f003, + 0x01020fb5, + 0x041fbb01, + 0x800112b6, + 0xf6010300, + 0x04bd0001, + 0x01040080, + 0xbd0001f6, + 0x01004104, + 0xa87e020f, + 0xb77e0006, + 0x100f0006, + 0x0006f97e, + 0x98000e98, + 0x207e010f, + 0x14950001, + 0xc0008008, + 0x0004f601, + 0x008004bd, + 0x04f601c1, + 0xb704bd00, + 0xbb130030, + 0xf5b6001f, + 0xd3008002, + 0x000ff601, + 0x15b604bd, + 0x0110b608, + 0xb20814b6, + 0x02687e1f, + 0x001fbb00, + 0x84020398, +/* 0x041f: init_gpc */ + 0xb8502000, + 0x0008044e, + 0x8f7e1fb2, + 0x4eb80000, + 0xbd00010c, + 0x008f7ef4, + 0x044eb800, + 0x8f7e0001, + 0x4eb80000, + 0x0f000100, + 0x008f7e02, + 0x004eb800, +/* 0x044e: init_gpc_wait */ + 0x657e0008, + 0xffc80000, + 0xf90bf41f, + 0x08044eb8, + 0x00657e00, + 0x001fbb00, + 0x800040b7, + 0xf40132b6, + 0x000fb41b, + 0x0006f97e, + 0xa87e000f, + 0x00800006, + 0x01f60201, + 0xbd04bd00, + 0x1f19f014, + 0x02300080, + 0xbd0001f6, +/* 0x0491: main */ + 0x0031f404, + 0x0d0028f4, + 0x00377e10, + 0xf401f400, + 0x4001e4b1, + 0x00c71bf5, + 0x99f094bd, + 0x37008004, + 0x0009f602, + 0x008104bd, + 0x11cf02c0, + 0xc1008200, + 0x0022cf02, + 0xf41f13c8, + 0x23c8770b, + 0x550bf41f, + 0x12b220f9, + 0x99f094bd, + 0x37008007, + 0x0009f602, + 0x32f404bd, + 0x0231f401, + 0x00087c7e, + 0x99f094bd, + 0x17008007, + 0x0009f602, + 0x20fc04bd, + 0x99f094bd, + 0x37008006, + 0x0009f602, + 0x31f404bd, + 0x087c7e01, + 0xf094bd00, + 0x00800699, + 0x09f60217, + 0xf404bd00, +/* 0x0522: chsw_prev_no_next */ + 0x20f92f0e, + 0x32f412b2, + 0x0232f401, + 0x00087c7e, + 0x008020fc, + 0x02f602c0, + 0xf404bd00, +/* 0x053e: chsw_no_prev */ + 0x23c8130e, + 0x0d0bf41f, + 0xf40131f4, + 0x7c7e0232, +/* 0x054e: chsw_done */ + 0x01020008, + 0x02c30080, + 0xbd0002f6, + 0xf094bd04, + 0x00800499, + 0x09f60217, + 0xf504bd00, +/* 0x056b: main_not_ctx_switch */ + 0xb0ff2a0e, + 0x1bf401e4, + 0x7ef2b20c, + 0xf400081c, +/* 0x057a: main_not_ctx_chan */ + 0xe4b0400e, + 0x2c1bf402, + 0x99f094bd, + 0x37008007, + 0x0009f602, + 0x32f404bd, + 0x0232f401, + 0x00087c7e, + 0x99f094bd, + 0x17008007, + 0x0009f602, + 0x0ef404bd, +/* 0x05a9: main_not_ctx_save */ + 0x10ef9411, + 0x7e01f5f0, + 0xf50002f8, +/* 0x05b7: main_done */ + 0xbdfede0e, + 0x1f29f024, + 0x02300080, + 0xbd0002f6, + 0xcc0ef504, +/* 0x05c9: ih */ + 0xfe80f9fe, + 0x80f90188, + 0xa0f990f9, + 0xd0f9b0f9, + 0xf0f9e0f9, + 0x004a04bd, + 0x00aacf02, + 0xf404abc4, + 0x100d230b, + 0xcf1a004e, + 0x004f00ee, + 0x00ffcf19, + 0x0000047e, + 0x0400b0b7, + 0x0040010e, + 0x000ef61d, +/* 0x060a: ih_no_fifo */ + 0xabe404bd, + 0x0bf40100, + 0x4e100d0c, + 0x047e4001, +/* 0x061a: ih_no_ctxsw */ + 0xabe40000, + 0x0bf40400, + 0x07088e56, + 0x00657e40, + 0x80ffb200, + 0xf6020400, + 0x04bd000f, + 0x4007048e, + 0x0000657e, + 0x0080ffb2, + 0x0ff60203, + 0xc704bd00, + 0xee9450fe, + 0x07008f02, + 0x00efbb40, + 0x0000657e, + 0x02020080, + 0xbd000ff6, + 0x7e030f04, + 0x4b0002f8, + 0xbfb20100, + 0x4001448e, + 0x00008f7e, +/* 0x0674: ih_no_fwmthd */ + 0xbd05044b, + 0xb4abffb0, + 0x800c0bf4, + 0xf6030700, + 0x04bd000b, +/* 0x0688: ih_no_other */ + 0xf6010040, + 0x04bd000a, + 0xe0fcf0fc, + 0xb0fcd0fc, + 0x90fca0fc, + 0x88fe80fc, + 0xf480fc00, + 0x01f80032, +/* 0x06a8: ctx_4170s */ + 0xb210f5f0, + 0x41708eff, + 0x008f7e40, +/* 0x06b7: ctx_4170w */ + 0x8e00f800, + 0x7e404170, + 0xb2000065, + 0x10f4f0ff, + 0xf8f31bf4, +/* 0x06c9: ctx_redswitch */ + 0x02004e00, + 0xf040e5f0, + 0xe5f020e5, + 0x85008010, + 0x000ef601, + 0x080f04bd, +/* 0x06e0: ctx_redswitch_delay */ + 0xf401f2b6, + 0xe5f1fd1b, + 0xe5f10400, + 0x00800100, + 0x0ef60185, + 0xf804bd00, +/* 0x06f9: ctx_86c */ + 0x23008000, + 0x000ff602, + 0xffb204bd, + 0x408a148e, + 0x00008f7e, + 0x8c8effb2, + 0x8f7e41a8, + 0x00f80000, +/* 0x0718: ctx_mem */ + 0x02840080, + 0xbd000ff6, +/* 0x0721: ctx_mem_wait */ + 0x84008f04, + 0x00ffcf02, + 0xf405fffd, + 0x00f8f61b, +/* 0x0730: ctx_load */ + 0x99f094bd, + 0x37008005, + 0x0009f602, + 0x0c0a04bd, + 0x0000b87e, + 0x0080f4bd, + 0x0ff60289, + 0x8004bd00, + 0xf602c100, + 0x04bd0002, + 0x02830080, + 0xbd0002f6, + 0x7e070f04, + 0x80000718, + 0xf602c000, + 0x04bd0002, + 0xf0000bfe, + 0x24b61f2a, + 0x0220b604, + 0x99f094bd, + 0x37008008, + 0x0009f602, + 0x008004bd, + 0x02f60281, + 0xd204bd00, + 0x80000000, + 0x800225f0, + 0xf6028800, + 0x04bd0002, + 0x00421001, + 0x0223f002, + 0xf80512fa, + 0xf094bd03, + 0x00800899, + 0x09f60217, + 0x9804bd00, + 0x14b68101, + 0x80029818, + 0xfd0825b6, + 0x01b50512, + 0xf094bd16, + 0x00800999, + 0x09f60237, + 0x8004bd00, + 0xf6028100, + 0x04bd0001, + 0x00800102, + 0x02f60288, + 0x4104bd00, + 0x13f00100, + 0x0501fa06, + 0x94bd03f8, + 0x800999f0, + 0xf6021700, + 0x04bd0009, + 0x99f094bd, + 0x17008005, + 0x0009f602, + 0x00f804bd, +/* 0x081c: ctx_chan */ + 0x0007307e, + 0xb87e0c0a, + 0x050f0000, + 0x0007187e, +/* 0x082e: ctx_mmio_exec */ + 0x039800f8, + 0x81008041, + 0x0003f602, + 0x34bd04bd, +/* 0x083c: ctx_mmio_loop */ + 0xf4ff34c4, + 0x00450e1b, + 0x0653f002, + 0xf80535fa, +/* 0x084d: ctx_mmio_pull */ + 0x804e9803, + 0x7e814f98, + 0xb600008f, + 0x12b60830, + 0xdf1bf401, +/* 0x0860: ctx_mmio_done */ + 0x80160398, + 0xf6028100, + 0x04bd0003, + 0x414000b5, + 0x13f00100, + 0x0601fa06, + 0x00f803f8, +/* 0x087c: ctx_xfer */ + 0x0080040e, + 0x0ef60302, +/* 0x0887: ctx_xfer_idle */ + 0x8e04bd00, + 0xcf030000, + 0xe4f100ee, + 0x1bf42000, + 0x0611f4f5, +/* 0x089b: ctx_xfer_pre */ + 0x0f0c02f4, + 0x06f97e10, + 0x1b11f400, +/* 0x08a4: ctx_xfer_pre_load */ + 0xa87e020f, + 0xb77e0006, + 0xc97e0006, + 0xf4bd0006, + 0x0006a87e, + 0x0007307e, +/* 0x08bc: ctx_xfer_exec */ + 0xbd160198, + 0x05008024, + 0x0002f601, + 0x1fb204bd, + 0x41a5008e, + 0x00008f7e, + 0xf001fcf0, + 0x24b6022c, + 0x05f2fd01, + 0x048effb2, + 0x8f7e41a5, + 0x167e0000, + 0x24bd0002, + 0x0247fc80, + 0xbd0002f6, + 0x012cf004, + 0x800320b6, + 0xf6024afc, + 0x04bd0002, + 0xf001acf0, + 0x000b06a5, + 0x98000c98, + 0x000e010d, + 0x00013d7e, + 0xec7e080a, + 0x0a7e0000, + 0x01f40002, + 0x7e0c0a12, + 0x0f0000b8, + 0x07187e05, + 0x2d02f400, +/* 0x0938: ctx_xfer_post */ + 0xa87e020f, + 0xf4bd0006, + 0x0006f97e, + 0x0002277e, + 0x0006b77e, + 0xa87ef4bd, + 0x11f40006, + 0x40019810, + 0xf40511fd, + 0x2e7e070b, +/* 0x0962: ctx_xfer_no_post_mmio */ +/* 0x0962: ctx_xfer_done */ + 0x00f80008, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h index 4750984bf38..e49b5a877ae 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h @@ -342,7 +342,7 @@ uint32_t nv108_grhub_code[] = { 0xb4f000bb, 0x10b4b01f, 0x0af31bf4, - 0x00b87e02, + 0x00b87e05, 0x250ef400, /* 0x01d8: mmctx_stop */ 0xb600abc8, @@ -478,10 +478,10 @@ uint32_t nv108_grhub_code[] = { 0x01040080, 0xbd0001f6, 0x01004104, - 0x627e020f, - 0x717e0006, + 0xa87e020f, + 0xb77e0006, 0x100f0006, - 0x0006b37e, + 0x0006f97e, 0x98000e98, 0x207e010f, 0x14950001, @@ -523,8 +523,8 @@ uint32_t nv108_grhub_code[] = { 0x800040b7, 0xf40132b6, 0x000fb41b, - 0x0006b37e, - 0x627e000f, + 0x0006f97e, + 0xa87e000f, 0x00800006, 0x01f60201, 0xbd04bd00, @@ -554,7 +554,7 @@ uint32_t nv108_grhub_code[] = { 0x0009f602, 0x32f404bd, 0x0231f401, - 0x0008367e, + 0x00087c7e, 0x99f094bd, 0x17008007, 0x0009f602, @@ -563,7 +563,7 @@ uint32_t nv108_grhub_code[] = { 0x37008006, 0x0009f602, 0x31f404bd, - 0x08367e01, + 0x087c7e01, 0xf094bd00, 0x00800699, 0x09f60217, @@ -572,7 +572,7 @@ uint32_t nv108_grhub_code[] = { 0x20f92f0e, 0x32f412b2, 0x0232f401, - 0x0008367e, + 0x00087c7e, 0x008020fc, 0x02f602c0, 0xf404bd00, @@ -580,7 +580,7 @@ uint32_t nv108_grhub_code[] = { 0x23c8130e, 0x0d0bf41f, 0xf40131f4, - 0x367e0232, + 0x7c7e0232, /* 0x054e: chsw_done */ 0x01020008, 0x02c30080, @@ -593,7 +593,7 @@ uint32_t nv108_grhub_code[] = { 0xb0ff2a0e, 0x1bf401e4, 0x7ef2b20c, - 0xf40007d6, + 0xf400081c, /* 0x057a: main_not_ctx_chan */ 0xe4b0400e, 0x2c1bf402, @@ -602,7 +602,7 @@ uint32_t nv108_grhub_code[] = { 0x0009f602, 0x32f404bd, 0x0232f401, - 0x0008367e, + 0x00087c7e, 0x99f094bd, 0x17008007, 0x0009f602, @@ -642,238 +642,238 @@ uint32_t nv108_grhub_code[] = { /* 0x061a: ih_no_ctxsw */ 0xabe40000, 0x0bf40400, - 0x01004b10, - 0x448ebfb2, - 0x8f7e4001, -/* 0x062e: ih_no_fwmthd */ - 0x044b0000, - 0xffb0bd01, - 0x0bf4b4ab, - 0x0700800c, - 0x000bf603, -/* 0x0642: ih_no_other */ - 0x004004bd, - 0x000af601, - 0xf0fc04bd, - 0xd0fce0fc, - 0xa0fcb0fc, - 0x80fc90fc, - 0xfc0088fe, - 0x0032f480, -/* 0x0662: ctx_4170s */ - 0xf5f001f8, - 0x8effb210, - 0x7e404170, - 0xf800008f, -/* 0x0671: ctx_4170w */ - 0x41708e00, + 0x07088e56, 0x00657e40, - 0xf0ffb200, - 0x1bf410f4, -/* 0x0683: ctx_redswitch */ - 0x4e00f8f3, - 0xe5f00200, - 0x20e5f040, - 0x8010e5f0, - 0xf6018500, - 0x04bd000e, -/* 0x069a: ctx_redswitch_delay */ - 0xf2b6080f, - 0xfd1bf401, - 0x0400e5f1, - 0x0100e5f1, - 0x01850080, - 0xbd000ef6, -/* 0x06b3: ctx_86c */ - 0x8000f804, - 0xf6022300, + 0x80ffb200, + 0xf6020400, 0x04bd000f, - 0x148effb2, - 0x8f7e408a, - 0xffb20000, - 0x41a88c8e, + 0x4007048e, + 0x0000657e, + 0x0080ffb2, + 0x0ff60203, + 0xc704bd00, + 0xee9450fe, + 0x07008f02, + 0x00efbb40, + 0x0000657e, + 0x02020080, + 0xbd000ff6, + 0x7e030f04, + 0x4b0002f8, + 0xbfb20100, + 0x4001448e, 0x00008f7e, -/* 0x06d2: ctx_mem */ - 0x008000f8, - 0x0ff60284, -/* 0x06db: ctx_mem_wait */ - 0x8f04bd00, - 0xcf028400, - 0xfffd00ff, - 0xf61bf405, -/* 0x06ea: ctx_load */ - 0x94bd00f8, - 0x800599f0, - 0xf6023700, - 0x04bd0009, - 0xb87e0c0a, - 0xf4bd0000, - 0x02890080, +/* 0x0674: ih_no_fwmthd */ + 0xbd05044b, + 0xb4abffb0, + 0x800c0bf4, + 0xf6030700, + 0x04bd000b, +/* 0x0688: ih_no_other */ + 0xf6010040, + 0x04bd000a, + 0xe0fcf0fc, + 0xb0fcd0fc, + 0x90fca0fc, + 0x88fe80fc, + 0xf480fc00, + 0x01f80032, +/* 0x06a8: ctx_4170s */ + 0xb210f5f0, + 0x41708eff, + 0x008f7e40, +/* 0x06b7: ctx_4170w */ + 0x8e00f800, + 0x7e404170, + 0xb2000065, + 0x10f4f0ff, + 0xf8f31bf4, +/* 0x06c9: ctx_redswitch */ + 0x02004e00, + 0xf040e5f0, + 0xe5f020e5, + 0x85008010, + 0x000ef601, + 0x080f04bd, +/* 0x06e0: ctx_redswitch_delay */ + 0xf401f2b6, + 0xe5f1fd1b, + 0xe5f10400, + 0x00800100, + 0x0ef60185, + 0xf804bd00, +/* 0x06f9: ctx_86c */ + 0x23008000, + 0x000ff602, + 0xffb204bd, + 0x408a148e, + 0x00008f7e, + 0x8c8effb2, + 0x8f7e41a8, + 0x00f80000, +/* 0x0718: ctx_mem */ + 0x02840080, 0xbd000ff6, - 0xc1008004, - 0x0002f602, - 0x008004bd, - 0x02f60283, - 0x0f04bd00, - 0x06d27e07, - 0xc0008000, - 0x0002f602, - 0x0bfe04bd, - 0x1f2af000, - 0xb60424b6, - 0x94bd0220, - 0x800899f0, - 0xf6023700, - 0x04bd0009, - 0x02810080, - 0xbd0002f6, - 0x0000d204, - 0x25f08000, - 0x88008002, - 0x0002f602, - 0x100104bd, - 0xf0020042, - 0x12fa0223, - 0xbd03f805, - 0x0899f094, - 0x02170080, - 0xbd0009f6, - 0x81019804, - 0x981814b6, - 0x25b68002, - 0x0512fd08, - 0xbd1601b5, - 0x0999f094, - 0x02370080, - 0xbd0009f6, - 0x81008004, - 0x0001f602, - 0x010204bd, - 0x02880080, +/* 0x0721: ctx_mem_wait */ + 0x84008f04, + 0x00ffcf02, + 0xf405fffd, + 0x00f8f61b, +/* 0x0730: ctx_load */ + 0x99f094bd, + 0x37008005, + 0x0009f602, + 0x0c0a04bd, + 0x0000b87e, + 0x0080f4bd, + 0x0ff60289, + 0x8004bd00, + 0xf602c100, + 0x04bd0002, + 0x02830080, 0xbd0002f6, - 0x01004104, - 0xfa0613f0, - 0x03f80501, + 0x7e070f04, + 0x80000718, + 0xf602c000, + 0x04bd0002, + 0xf0000bfe, + 0x24b61f2a, + 0x0220b604, 0x99f094bd, - 0x17008009, + 0x37008008, 0x0009f602, - 0x94bd04bd, - 0x800599f0, + 0x008004bd, + 0x02f60281, + 0xd204bd00, + 0x80000000, + 0x800225f0, + 0xf6028800, + 0x04bd0002, + 0x00421001, + 0x0223f002, + 0xf80512fa, + 0xf094bd03, + 0x00800899, + 0x09f60217, + 0x9804bd00, + 0x14b68101, + 0x80029818, + 0xfd0825b6, + 0x01b50512, + 0xf094bd16, + 0x00800999, + 0x09f60237, + 0x8004bd00, + 0xf6028100, + 0x04bd0001, + 0x00800102, + 0x02f60288, + 0x4104bd00, + 0x13f00100, + 0x0501fa06, + 0x94bd03f8, + 0x800999f0, 0xf6021700, 0x04bd0009, -/* 0x07d6: ctx_chan */ - 0xea7e00f8, - 0x0c0a0006, - 0x0000b87e, - 0xd27e050f, - 0x00f80006, -/* 0x07e8: ctx_mmio_exec */ - 0x80410398, + 0x99f094bd, + 0x17008005, + 0x0009f602, + 0x00f804bd, +/* 0x081c: ctx_chan */ + 0x0007307e, + 0xb87e0c0a, + 0x050f0000, + 0x0007187e, +/* 0x082e: ctx_mmio_exec */ + 0x039800f8, + 0x81008041, + 0x0003f602, + 0x34bd04bd, +/* 0x083c: ctx_mmio_loop */ + 0xf4ff34c4, + 0x00450e1b, + 0x0653f002, + 0xf80535fa, +/* 0x084d: ctx_mmio_pull */ + 0x804e9803, + 0x7e814f98, + 0xb600008f, + 0x12b60830, + 0xdf1bf401, +/* 0x0860: ctx_mmio_done */ + 0x80160398, 0xf6028100, 0x04bd0003, -/* 0x07f6: ctx_mmio_loop */ - 0x34c434bd, - 0x0e1bf4ff, - 0xf0020045, - 0x35fa0653, -/* 0x0807: ctx_mmio_pull */ - 0x9803f805, - 0x4f98804e, - 0x008f7e81, - 0x0830b600, - 0xf40112b6, -/* 0x081a: ctx_mmio_done */ - 0x0398df1b, - 0x81008016, - 0x0003f602, - 0x00b504bd, - 0x01004140, - 0xfa0613f0, - 0x03f80601, -/* 0x0836: ctx_xfer */ - 0x040e00f8, - 0x03020080, - 0xbd000ef6, -/* 0x0841: ctx_xfer_idle */ - 0x00008e04, - 0x00eecf03, - 0x2000e4f1, - 0xf4f51bf4, - 0x02f40611, -/* 0x0855: ctx_xfer_pre */ - 0x7e100f0c, - 0xf40006b3, -/* 0x085e: ctx_xfer_pre_load */ - 0x020f1b11, - 0x0006627e, - 0x0006717e, - 0x0006837e, - 0x627ef4bd, - 0xea7e0006, -/* 0x0876: ctx_xfer_exec */ - 0x01980006, - 0x8024bd16, - 0xf6010500, - 0x04bd0002, - 0x008e1fb2, - 0x8f7e41a5, - 0xfcf00000, - 0x022cf001, - 0xfd0124b6, - 0xffb205f2, - 0x41a5048e, + 0x414000b5, + 0x13f00100, + 0x0601fa06, + 0x00f803f8, +/* 0x087c: ctx_xfer */ + 0x0080040e, + 0x0ef60302, +/* 0x0887: ctx_xfer_idle */ + 0x8e04bd00, + 0xcf030000, + 0xe4f100ee, + 0x1bf42000, + 0x0611f4f5, +/* 0x089b: ctx_xfer_pre */ + 0x0f0c02f4, + 0x06f97e10, + 0x1b11f400, +/* 0x08a4: ctx_xfer_pre_load */ + 0xa87e020f, + 0xb77e0006, + 0xc97e0006, + 0xf4bd0006, + 0x0006a87e, + 0x0007307e, +/* 0x08bc: ctx_xfer_exec */ + 0xbd160198, + 0x05008024, + 0x0002f601, + 0x1fb204bd, + 0x41a5008e, 0x00008f7e, - 0x0002167e, - 0xfc8024bd, - 0x02f60247, - 0xf004bd00, - 0x20b6012c, - 0x4afc8003, - 0x0002f602, - 0xacf004bd, - 0x06a5f001, - 0x0c98000b, - 0x010d9800, - 0x3d7e000e, - 0x080a0001, - 0x0000ec7e, - 0x00020a7e, - 0x0a1201f4, - 0x00b87e0c, - 0x7e050f00, - 0xf40006d2, -/* 0x08f2: ctx_xfer_post */ - 0x020f2d02, - 0x0006627e, - 0xb37ef4bd, - 0x277e0006, - 0x717e0002, + 0xf001fcf0, + 0x24b6022c, + 0x05f2fd01, + 0x048effb2, + 0x8f7e41a5, + 0x167e0000, + 0x24bd0002, + 0x0247fc80, + 0xbd0002f6, + 0x012cf004, + 0x800320b6, + 0xf6024afc, + 0x04bd0002, + 0xf001acf0, + 0x000b06a5, + 0x98000c98, + 0x000e010d, + 0x00013d7e, + 0xec7e080a, + 0x0a7e0000, + 0x01f40002, + 0x7e0c0a12, + 0x0f0000b8, + 0x07187e05, + 0x2d02f400, +/* 0x0938: ctx_xfer_post */ + 0xa87e020f, 0xf4bd0006, - 0x0006627e, - 0x981011f4, - 0x11fd4001, - 0x070bf405, - 0x0007e87e, -/* 0x091c: ctx_xfer_no_post_mmio */ -/* 0x091c: ctx_xfer_done */ - 0x000000f8, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, + 0x0006f97e, + 0x0002277e, + 0x0006b77e, + 0xa87ef4bd, + 0x11f40006, + 0x40019810, + 0xf40511fd, + 0x2e7e070b, +/* 0x0962: ctx_xfer_no_post_mmio */ +/* 0x0962: ctx_xfer_done */ + 0x00f80008, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h index 132f684b194..92dfe6a4ac8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h @@ -361,7 +361,7 @@ uint32_t nvc0_grhub_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -528,10 +528,10 @@ uint32_t nvc0_grhub_code[] = { 0x0001d001, 0x17f104bd, 0xf7f00100, - 0xb521f502, - 0xc721f507, - 0x10f7f007, - 0x081421f5, + 0x0d21f502, + 0x1f21f508, + 0x10f7f008, + 0x086c21f5, 0x98000e98, 0x21f5010f, 0x14950150, @@ -574,9 +574,9 @@ uint32_t nvc0_grhub_code[] = { 0xb6800040, 0x1bf40132, 0x00f7f0be, - 0x081421f5, + 0x086c21f5, 0xf500f7f0, - 0xf107b521, + 0xf1080d21, 0xf0010007, 0x01d00203, 0xbd04bd00, @@ -610,8 +610,8 @@ uint32_t nvc0_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x31f40132, - 0xe821f502, - 0xf094bd09, + 0x4021f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -621,7 +621,7 @@ uint32_t nvc0_grhub_code[] = { 0x0203f00f, 0xbd0009d0, 0x0131f404, - 0x09e821f5, + 0x0a4021f5, 0x99f094bd, 0x0007f106, 0x0203f017, @@ -631,7 +631,7 @@ uint32_t nvc0_grhub_code[] = { 0x12b920f9, 0x0132f402, 0xf50232f4, - 0xfc09e821, + 0xfc0a4021, 0x0007f120, 0x0203f0c0, 0xbd0002d0, @@ -640,7 +640,7 @@ uint32_t nvc0_grhub_code[] = { 0xf41f23c8, 0x31f40d0b, 0x0232f401, - 0x09e821f5, + 0x0a4021f5, /* 0x063c: chsw_done */ 0xf10127f0, 0xf0c30007, @@ -654,7 +654,7 @@ uint32_t nvc0_grhub_code[] = { /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, - 0x7821f502, + 0xd021f502, 0x460ef409, /* 0x0670: main_not_ctx_chan */ 0xf402e4b0, @@ -664,8 +664,8 @@ uint32_t nvc0_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x32f40132, - 0xe821f502, - 0xf094bd09, + 0x4021f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -710,18 +710,40 @@ uint32_t nvc0_grhub_code[] = { /* 0x072b: ih_no_ctxsw */ 0xe40421f4, 0xf40400ab, - 0xb7f1140b, + 0xe7f16c0b, + 0xe3f00708, + 0x6821f440, + 0xf102ffb9, + 0xf0040007, + 0x0fd00203, + 0xf104bd00, + 0xf00704e7, + 0x21f440e3, + 0x02ffb968, + 0x030007f1, + 0xd00203f0, + 0x04bd000f, + 0x9450fec7, + 0xf7f102ee, + 0xf3f00700, + 0x00efbb40, + 0xf16821f4, + 0xf0020007, + 0x0fd00203, + 0xf004bd00, + 0x21f503f7, + 0xb7f1037e, 0xbfb90100, 0x44e7f102, 0x40e3f001, -/* 0x0743: ih_no_fwmthd */ +/* 0x079b: ih_no_fwmthd */ 0xf19d21f4, - 0xbd0104b7, + 0xbd0504b7, 0xb4abffb0, 0xf10f0bf4, 0xf0070007, 0x0bd00303, -/* 0x075b: ih_no_other */ +/* 0x07b3: ih_no_other */ 0xf104bd00, 0xf0010007, 0x0ad00003, @@ -731,36 +753,36 @@ uint32_t nvc0_grhub_code[] = { 0xfc90fca0, 0x0088fe80, 0x32f480fc, -/* 0x077f: ctx_4160s */ +/* 0x07d7: ctx_4160s */ 0xf001f800, 0xffb901f7, 0x60e7f102, 0x40e3f041, -/* 0x078f: ctx_4160s_wait */ +/* 0x07e7: ctx_4160s_wait */ 0xf19d21f4, 0xf04160e7, 0x21f440e3, 0x02ffb968, 0xf404ffc8, 0x00f8f00b, -/* 0x07a4: ctx_4160c */ +/* 0x07fc: ctx_4160c */ 0xffb9f4bd, 0x60e7f102, 0x40e3f041, 0xf89d21f4, -/* 0x07b5: ctx_4170s */ +/* 0x080d: ctx_4170s */ 0x10f5f000, 0xf102ffb9, 0xf04170e7, 0x21f440e3, -/* 0x07c7: ctx_4170w */ +/* 0x081f: ctx_4170w */ 0xf100f89d, 0xf04170e7, 0x21f440e3, 0x02ffb968, 0xf410f4f0, 0x00f8f01b, -/* 0x07dc: ctx_redswitch */ +/* 0x0834: ctx_redswitch */ 0x0200e7f1, 0xf040e5f0, 0xe5f020e5, @@ -768,7 +790,7 @@ uint32_t nvc0_grhub_code[] = { 0x0103f085, 0xbd000ed0, 0x08f7f004, -/* 0x07f8: ctx_redswitch_delay */ +/* 0x0850: ctx_redswitch_delay */ 0xf401f2b6, 0xe5f1fd1b, 0xe5f10400, @@ -776,7 +798,7 @@ uint32_t nvc0_grhub_code[] = { 0x03f08500, 0x000ed001, 0x00f804bd, -/* 0x0814: ctx_86c */ +/* 0x086c: ctx_86c */ 0x1b0007f1, 0xd00203f0, 0x04bd000f, @@ -787,16 +809,16 @@ uint32_t nvc0_grhub_code[] = { 0xa86ce7f1, 0xf441e3f0, 0x00f89d21, -/* 0x083c: ctx_mem */ +/* 0x0894: ctx_mem */ 0x840007f1, 0xd00203f0, 0x04bd000f, -/* 0x0848: ctx_mem_wait */ +/* 0x08a0: ctx_mem_wait */ 0x8400f7f1, 0xcf02f3f0, 0xfffd00ff, 0xf31bf405, -/* 0x085a: ctx_load */ +/* 0x08b2: ctx_load */ 0x94bd00f8, 0xf10599f0, 0xf00f0007, @@ -814,7 +836,7 @@ uint32_t nvc0_grhub_code[] = { 0x02d00203, 0xf004bd00, 0x21f507f7, - 0x07f1083c, + 0x07f10894, 0x03f0c000, 0x0002d002, 0x0bfe04bd, @@ -869,31 +891,31 @@ uint32_t nvc0_grhub_code[] = { 0x03f01700, 0x0009d002, 0x00f804bd, -/* 0x0978: ctx_chan */ - 0x077f21f5, - 0x085a21f5, +/* 0x09d0: ctx_chan */ + 0x07d721f5, + 0x08b221f5, 0xf40ca7f0, 0xf7f0d021, - 0x3c21f505, - 0xa421f508, -/* 0x0993: ctx_mmio_exec */ + 0x9421f505, + 0xfc21f508, +/* 0x09eb: ctx_mmio_exec */ 0x9800f807, 0x07f14103, 0x03f08100, 0x0003d002, 0x34bd04bd, -/* 0x09a4: ctx_mmio_loop */ +/* 0x09fc: ctx_mmio_loop */ 0xf4ff34c4, 0x57f10f1b, 0x53f00200, 0x0535fa06, -/* 0x09b6: ctx_mmio_pull */ +/* 0x0a0e: ctx_mmio_pull */ 0x4e9803f8, 0x814f9880, 0xb69d21f4, 0x12b60830, 0xdf1bf401, -/* 0x09c8: ctx_mmio_done */ +/* 0x0a20: ctx_mmio_done */ 0xf1160398, 0xf0810007, 0x03d00203, @@ -902,30 +924,30 @@ uint32_t nvc0_grhub_code[] = { 0x13f00100, 0x0601fa06, 0x00f803f8, -/* 0x09e8: ctx_xfer */ +/* 0x0a40: ctx_xfer */ 0xf104e7f0, 0xf0020007, 0x0ed00303, -/* 0x09f7: ctx_xfer_idle */ +/* 0x0a4f: ctx_xfer_idle */ 0xf104bd00, 0xf00000e7, 0xeecf03e3, 0x00e4f100, 0xf21bf420, 0xf40611f4, -/* 0x0a0e: ctx_xfer_pre */ +/* 0x0a66: ctx_xfer_pre */ 0xf7f01102, - 0x1421f510, - 0x7f21f508, + 0x6c21f510, + 0xd721f508, 0x1c11f407, -/* 0x0a1c: ctx_xfer_pre_load */ +/* 0x0a74: ctx_xfer_pre_load */ 0xf502f7f0, - 0xf507b521, - 0xf507c721, - 0xbd07dc21, - 0xb521f5f4, - 0x5a21f507, -/* 0x0a35: ctx_xfer_exec */ + 0xf5080d21, + 0xf5081f21, + 0xbd083421, + 0x0d21f5f4, + 0xb221f508, +/* 0x0a8d: ctx_xfer_exec */ 0x16019808, 0x07f124bd, 0x03f00500, @@ -960,23 +982,65 @@ uint32_t nvc0_grhub_code[] = { 0x1301f402, 0xf40ca7f0, 0xf7f0d021, - 0x3c21f505, + 0x9421f505, 0x3202f408, -/* 0x0ac4: ctx_xfer_post */ +/* 0x0b1c: ctx_xfer_post */ 0xf502f7f0, - 0xbd07b521, - 0x1421f5f4, + 0xbd080d21, + 0x6c21f5f4, 0x7f21f508, - 0xc721f502, - 0xf5f4bd07, - 0xf407b521, + 0x1f21f502, + 0xf5f4bd08, + 0xf4080d21, 0x01981011, 0x0511fd40, 0xf5070bf4, -/* 0x0aef: ctx_xfer_no_post_mmio */ - 0xf5099321, -/* 0x0af3: ctx_xfer_done */ - 0xf807a421, +/* 0x0b47: ctx_xfer_no_post_mmio */ + 0xf509eb21, +/* 0x0b4b: ctx_xfer_done */ + 0xf807fc21, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h index 84af8241898..62b0c7601d8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h @@ -361,7 +361,7 @@ uint32_t nvd7_grhub_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -528,10 +528,10 @@ uint32_t nvd7_grhub_code[] = { 0x0001d001, 0x17f104bd, 0xf7f00100, - 0xb521f502, - 0xc721f507, - 0x10f7f007, - 0x081421f5, + 0x0d21f502, + 0x1f21f508, + 0x10f7f008, + 0x086c21f5, 0x98000e98, 0x21f5010f, 0x14950150, @@ -574,9 +574,9 @@ uint32_t nvd7_grhub_code[] = { 0xb6800040, 0x1bf40132, 0x00f7f0be, - 0x081421f5, + 0x086c21f5, 0xf500f7f0, - 0xf107b521, + 0xf1080d21, 0xf0010007, 0x01d00203, 0xbd04bd00, @@ -610,8 +610,8 @@ uint32_t nvd7_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x31f40132, - 0xe821f502, - 0xf094bd09, + 0x4021f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -621,7 +621,7 @@ uint32_t nvd7_grhub_code[] = { 0x0203f00f, 0xbd0009d0, 0x0131f404, - 0x09e821f5, + 0x0a4021f5, 0x99f094bd, 0x0007f106, 0x0203f017, @@ -631,7 +631,7 @@ uint32_t nvd7_grhub_code[] = { 0x12b920f9, 0x0132f402, 0xf50232f4, - 0xfc09e821, + 0xfc0a4021, 0x0007f120, 0x0203f0c0, 0xbd0002d0, @@ -640,7 +640,7 @@ uint32_t nvd7_grhub_code[] = { 0xf41f23c8, 0x31f40d0b, 0x0232f401, - 0x09e821f5, + 0x0a4021f5, /* 0x063c: chsw_done */ 0xf10127f0, 0xf0c30007, @@ -654,7 +654,7 @@ uint32_t nvd7_grhub_code[] = { /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, - 0x7821f502, + 0xd021f502, 0x460ef409, /* 0x0670: main_not_ctx_chan */ 0xf402e4b0, @@ -664,8 +664,8 @@ uint32_t nvd7_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x32f40132, - 0xe821f502, - 0xf094bd09, + 0x4021f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -710,18 +710,40 @@ uint32_t nvd7_grhub_code[] = { /* 0x072b: ih_no_ctxsw */ 0xe40421f4, 0xf40400ab, - 0xb7f1140b, + 0xe7f16c0b, + 0xe3f00708, + 0x6821f440, + 0xf102ffb9, + 0xf0040007, + 0x0fd00203, + 0xf104bd00, + 0xf00704e7, + 0x21f440e3, + 0x02ffb968, + 0x030007f1, + 0xd00203f0, + 0x04bd000f, + 0x9450fec7, + 0xf7f102ee, + 0xf3f00700, + 0x00efbb40, + 0xf16821f4, + 0xf0020007, + 0x0fd00203, + 0xf004bd00, + 0x21f503f7, + 0xb7f1037e, 0xbfb90100, 0x44e7f102, 0x40e3f001, -/* 0x0743: ih_no_fwmthd */ +/* 0x079b: ih_no_fwmthd */ 0xf19d21f4, - 0xbd0104b7, + 0xbd0504b7, 0xb4abffb0, 0xf10f0bf4, 0xf0070007, 0x0bd00303, -/* 0x075b: ih_no_other */ +/* 0x07b3: ih_no_other */ 0xf104bd00, 0xf0010007, 0x0ad00003, @@ -731,36 +753,36 @@ uint32_t nvd7_grhub_code[] = { 0xfc90fca0, 0x0088fe80, 0x32f480fc, -/* 0x077f: ctx_4160s */ +/* 0x07d7: ctx_4160s */ 0xf001f800, 0xffb901f7, 0x60e7f102, 0x40e3f041, -/* 0x078f: ctx_4160s_wait */ +/* 0x07e7: ctx_4160s_wait */ 0xf19d21f4, 0xf04160e7, 0x21f440e3, 0x02ffb968, 0xf404ffc8, 0x00f8f00b, -/* 0x07a4: ctx_4160c */ +/* 0x07fc: ctx_4160c */ 0xffb9f4bd, 0x60e7f102, 0x40e3f041, 0xf89d21f4, -/* 0x07b5: ctx_4170s */ +/* 0x080d: ctx_4170s */ 0x10f5f000, 0xf102ffb9, 0xf04170e7, 0x21f440e3, -/* 0x07c7: ctx_4170w */ +/* 0x081f: ctx_4170w */ 0xf100f89d, 0xf04170e7, 0x21f440e3, 0x02ffb968, 0xf410f4f0, 0x00f8f01b, -/* 0x07dc: ctx_redswitch */ +/* 0x0834: ctx_redswitch */ 0x0200e7f1, 0xf040e5f0, 0xe5f020e5, @@ -768,7 +790,7 @@ uint32_t nvd7_grhub_code[] = { 0x0103f085, 0xbd000ed0, 0x08f7f004, -/* 0x07f8: ctx_redswitch_delay */ +/* 0x0850: ctx_redswitch_delay */ 0xf401f2b6, 0xe5f1fd1b, 0xe5f10400, @@ -776,7 +798,7 @@ uint32_t nvd7_grhub_code[] = { 0x03f08500, 0x000ed001, 0x00f804bd, -/* 0x0814: ctx_86c */ +/* 0x086c: ctx_86c */ 0x1b0007f1, 0xd00203f0, 0x04bd000f, @@ -787,16 +809,16 @@ uint32_t nvd7_grhub_code[] = { 0xa86ce7f1, 0xf441e3f0, 0x00f89d21, -/* 0x083c: ctx_mem */ +/* 0x0894: ctx_mem */ 0x840007f1, 0xd00203f0, 0x04bd000f, -/* 0x0848: ctx_mem_wait */ +/* 0x08a0: ctx_mem_wait */ 0x8400f7f1, 0xcf02f3f0, 0xfffd00ff, 0xf31bf405, -/* 0x085a: ctx_load */ +/* 0x08b2: ctx_load */ 0x94bd00f8, 0xf10599f0, 0xf00f0007, @@ -814,7 +836,7 @@ uint32_t nvd7_grhub_code[] = { 0x02d00203, 0xf004bd00, 0x21f507f7, - 0x07f1083c, + 0x07f10894, 0x03f0c000, 0x0002d002, 0x0bfe04bd, @@ -869,31 +891,31 @@ uint32_t nvd7_grhub_code[] = { 0x03f01700, 0x0009d002, 0x00f804bd, -/* 0x0978: ctx_chan */ - 0x077f21f5, - 0x085a21f5, +/* 0x09d0: ctx_chan */ + 0x07d721f5, + 0x08b221f5, 0xf40ca7f0, 0xf7f0d021, - 0x3c21f505, - 0xa421f508, -/* 0x0993: ctx_mmio_exec */ + 0x9421f505, + 0xfc21f508, +/* 0x09eb: ctx_mmio_exec */ 0x9800f807, 0x07f14103, 0x03f08100, 0x0003d002, 0x34bd04bd, -/* 0x09a4: ctx_mmio_loop */ +/* 0x09fc: ctx_mmio_loop */ 0xf4ff34c4, 0x57f10f1b, 0x53f00200, 0x0535fa06, -/* 0x09b6: ctx_mmio_pull */ +/* 0x0a0e: ctx_mmio_pull */ 0x4e9803f8, 0x814f9880, 0xb69d21f4, 0x12b60830, 0xdf1bf401, -/* 0x09c8: ctx_mmio_done */ +/* 0x0a20: ctx_mmio_done */ 0xf1160398, 0xf0810007, 0x03d00203, @@ -902,30 +924,30 @@ uint32_t nvd7_grhub_code[] = { 0x13f00100, 0x0601fa06, 0x00f803f8, -/* 0x09e8: ctx_xfer */ +/* 0x0a40: ctx_xfer */ 0xf104e7f0, 0xf0020007, 0x0ed00303, -/* 0x09f7: ctx_xfer_idle */ +/* 0x0a4f: ctx_xfer_idle */ 0xf104bd00, 0xf00000e7, 0xeecf03e3, 0x00e4f100, 0xf21bf420, 0xf40611f4, -/* 0x0a0e: ctx_xfer_pre */ +/* 0x0a66: ctx_xfer_pre */ 0xf7f01102, - 0x1421f510, - 0x7f21f508, + 0x6c21f510, + 0xd721f508, 0x1c11f407, -/* 0x0a1c: ctx_xfer_pre_load */ +/* 0x0a74: ctx_xfer_pre_load */ 0xf502f7f0, - 0xf507b521, - 0xf507c721, - 0xbd07dc21, - 0xb521f5f4, - 0x5a21f507, -/* 0x0a35: ctx_xfer_exec */ + 0xf5080d21, + 0xf5081f21, + 0xbd083421, + 0x0d21f5f4, + 0xb221f508, +/* 0x0a8d: ctx_xfer_exec */ 0x16019808, 0x07f124bd, 0x03f00500, @@ -960,23 +982,65 @@ uint32_t nvd7_grhub_code[] = { 0x1301f402, 0xf40ca7f0, 0xf7f0d021, - 0x3c21f505, + 0x9421f505, 0x3202f408, -/* 0x0ac4: ctx_xfer_post */ +/* 0x0b1c: ctx_xfer_post */ 0xf502f7f0, - 0xbd07b521, - 0x1421f5f4, + 0xbd080d21, + 0x6c21f5f4, 0x7f21f508, - 0xc721f502, - 0xf5f4bd07, - 0xf407b521, + 0x1f21f502, + 0xf5f4bd08, + 0xf4080d21, 0x01981011, 0x0511fd40, 0xf5070bf4, -/* 0x0aef: ctx_xfer_no_post_mmio */ - 0xf5099321, -/* 0x0af3: ctx_xfer_done */ - 0xf807a421, +/* 0x0b47: ctx_xfer_no_post_mmio */ + 0xf509eb21, +/* 0x0b4b: ctx_xfer_done */ + 0xf807fc21, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h index 1c179bdd48c..51c3797d853 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h @@ -361,7 +361,7 @@ uint32_t nve0_grhub_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -528,10 +528,10 @@ uint32_t nve0_grhub_code[] = { 0x0001d001, 0x17f104bd, 0xf7f00100, - 0x7f21f502, - 0x9121f507, + 0xd721f502, + 0xe921f507, 0x10f7f007, - 0x07de21f5, + 0x083621f5, 0x98000e98, 0x21f5010f, 0x14950150, @@ -574,9 +574,9 @@ uint32_t nve0_grhub_code[] = { 0xb6800040, 0x1bf40132, 0x00f7f0be, - 0x07de21f5, + 0x083621f5, 0xf500f7f0, - 0xf1077f21, + 0xf107d721, 0xf0010007, 0x01d00203, 0xbd04bd00, @@ -610,8 +610,8 @@ uint32_t nve0_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x31f40132, - 0xaa21f502, - 0xf094bd09, + 0x0221f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -621,7 +621,7 @@ uint32_t nve0_grhub_code[] = { 0x0203f00f, 0xbd0009d0, 0x0131f404, - 0x09aa21f5, + 0x0a0221f5, 0x99f094bd, 0x0007f106, 0x0203f017, @@ -631,7 +631,7 @@ uint32_t nve0_grhub_code[] = { 0x12b920f9, 0x0132f402, 0xf50232f4, - 0xfc09aa21, + 0xfc0a0221, 0x0007f120, 0x0203f0c0, 0xbd0002d0, @@ -640,7 +640,7 @@ uint32_t nve0_grhub_code[] = { 0xf41f23c8, 0x31f40d0b, 0x0232f401, - 0x09aa21f5, + 0x0a0221f5, /* 0x063c: chsw_done */ 0xf10127f0, 0xf0c30007, @@ -654,7 +654,7 @@ uint32_t nve0_grhub_code[] = { /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, - 0x4221f502, + 0x9a21f502, 0x460ef409, /* 0x0670: main_not_ctx_chan */ 0xf402e4b0, @@ -664,8 +664,8 @@ uint32_t nve0_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x32f40132, - 0xaa21f502, - 0xf094bd09, + 0x0221f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -710,18 +710,40 @@ uint32_t nve0_grhub_code[] = { /* 0x072b: ih_no_ctxsw */ 0xe40421f4, 0xf40400ab, - 0xb7f1140b, + 0xe7f16c0b, + 0xe3f00708, + 0x6821f440, + 0xf102ffb9, + 0xf0040007, + 0x0fd00203, + 0xf104bd00, + 0xf00704e7, + 0x21f440e3, + 0x02ffb968, + 0x030007f1, + 0xd00203f0, + 0x04bd000f, + 0x9450fec7, + 0xf7f102ee, + 0xf3f00700, + 0x00efbb40, + 0xf16821f4, + 0xf0020007, + 0x0fd00203, + 0xf004bd00, + 0x21f503f7, + 0xb7f1037e, 0xbfb90100, 0x44e7f102, 0x40e3f001, -/* 0x0743: ih_no_fwmthd */ +/* 0x079b: ih_no_fwmthd */ 0xf19d21f4, - 0xbd0104b7, + 0xbd0504b7, 0xb4abffb0, 0xf10f0bf4, 0xf0070007, 0x0bd00303, -/* 0x075b: ih_no_other */ +/* 0x07b3: ih_no_other */ 0xf104bd00, 0xf0010007, 0x0ad00003, @@ -731,19 +753,19 @@ uint32_t nve0_grhub_code[] = { 0xfc90fca0, 0x0088fe80, 0x32f480fc, -/* 0x077f: ctx_4170s */ +/* 0x07d7: ctx_4170s */ 0xf001f800, 0xffb910f5, 0x70e7f102, 0x40e3f041, 0xf89d21f4, -/* 0x0791: ctx_4170w */ +/* 0x07e9: ctx_4170w */ 0x70e7f100, 0x40e3f041, 0xb96821f4, 0xf4f002ff, 0xf01bf410, -/* 0x07a6: ctx_redswitch */ +/* 0x07fe: ctx_redswitch */ 0xe7f100f8, 0xe5f00200, 0x20e5f040, @@ -751,7 +773,7 @@ uint32_t nve0_grhub_code[] = { 0xf0850007, 0x0ed00103, 0xf004bd00, -/* 0x07c2: ctx_redswitch_delay */ +/* 0x081a: ctx_redswitch_delay */ 0xf2b608f7, 0xfd1bf401, 0x0400e5f1, @@ -759,7 +781,7 @@ uint32_t nve0_grhub_code[] = { 0x850007f1, 0xd00103f0, 0x04bd000e, -/* 0x07de: ctx_86c */ +/* 0x0836: ctx_86c */ 0x07f100f8, 0x03f01b00, 0x000fd002, @@ -770,17 +792,17 @@ uint32_t nve0_grhub_code[] = { 0xe7f102ff, 0xe3f0a86c, 0x9d21f441, -/* 0x0806: ctx_mem */ +/* 0x085e: ctx_mem */ 0x07f100f8, 0x03f08400, 0x000fd002, -/* 0x0812: ctx_mem_wait */ +/* 0x086a: ctx_mem_wait */ 0xf7f104bd, 0xf3f08400, 0x00ffcf02, 0xf405fffd, 0x00f8f31b, -/* 0x0824: ctx_load */ +/* 0x087c: ctx_load */ 0x99f094bd, 0x0007f105, 0x0203f00f, @@ -797,7 +819,7 @@ uint32_t nve0_grhub_code[] = { 0x0203f083, 0xbd0002d0, 0x07f7f004, - 0x080621f5, + 0x085e21f5, 0xc00007f1, 0xd00203f0, 0x04bd0002, @@ -852,29 +874,29 @@ uint32_t nve0_grhub_code[] = { 0x170007f1, 0xd00203f0, 0x04bd0009, -/* 0x0942: ctx_chan */ +/* 0x099a: ctx_chan */ 0x21f500f8, - 0xa7f00824, + 0xa7f0087c, 0xd021f40c, 0xf505f7f0, - 0xf8080621, -/* 0x0955: ctx_mmio_exec */ + 0xf8085e21, +/* 0x09ad: ctx_mmio_exec */ 0x41039800, 0x810007f1, 0xd00203f0, 0x04bd0003, -/* 0x0966: ctx_mmio_loop */ +/* 0x09be: ctx_mmio_loop */ 0x34c434bd, 0x0f1bf4ff, 0x020057f1, 0xfa0653f0, 0x03f80535, -/* 0x0978: ctx_mmio_pull */ +/* 0x09d0: ctx_mmio_pull */ 0x98804e98, 0x21f4814f, 0x0830b69d, 0xf40112b6, -/* 0x098a: ctx_mmio_done */ +/* 0x09e2: ctx_mmio_done */ 0x0398df1b, 0x0007f116, 0x0203f081, @@ -883,30 +905,30 @@ uint32_t nve0_grhub_code[] = { 0x010017f1, 0xfa0613f0, 0x03f80601, -/* 0x09aa: ctx_xfer */ +/* 0x0a02: ctx_xfer */ 0xe7f000f8, 0x0007f104, 0x0303f002, 0xbd000ed0, -/* 0x09b9: ctx_xfer_idle */ +/* 0x0a11: ctx_xfer_idle */ 0x00e7f104, 0x03e3f000, 0xf100eecf, 0xf42000e4, 0x11f4f21b, 0x0d02f406, -/* 0x09d0: ctx_xfer_pre */ +/* 0x0a28: ctx_xfer_pre */ 0xf510f7f0, - 0xf407de21, -/* 0x09da: ctx_xfer_pre_load */ + 0xf4083621, +/* 0x0a32: ctx_xfer_pre_load */ 0xf7f01c11, - 0x7f21f502, - 0x9121f507, - 0xa621f507, + 0xd721f502, + 0xe921f507, + 0xfe21f507, 0xf5f4bd07, - 0xf5077f21, -/* 0x09f3: ctx_xfer_exec */ - 0x98082421, + 0xf507d721, +/* 0x0a4b: ctx_xfer_exec */ + 0x98087c21, 0x24bd1601, 0x050007f1, 0xd00103f0, @@ -941,21 +963,21 @@ uint32_t nve0_grhub_code[] = { 0xa7f01301, 0xd021f40c, 0xf505f7f0, - 0xf4080621, -/* 0x0a82: ctx_xfer_post */ + 0xf4085e21, +/* 0x0ada: ctx_xfer_post */ 0xf7f02e02, - 0x7f21f502, + 0xd721f502, 0xf5f4bd07, - 0xf507de21, + 0xf5083621, 0xf5027f21, - 0xbd079121, - 0x7f21f5f4, + 0xbd07e921, + 0xd721f5f4, 0x1011f407, 0xfd400198, 0x0bf40511, - 0x5521f507, -/* 0x0aad: ctx_xfer_no_post_mmio */ -/* 0x0aad: ctx_xfer_done */ + 0xad21f507, +/* 0x0b05: ctx_xfer_no_post_mmio */ +/* 0x0b05: ctx_xfer_done */ 0x0000f809, 0x00000000, 0x00000000, @@ -977,4 +999,46 @@ uint32_t nve0_grhub_code[] = { 0x00000000, 0x00000000, 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h index 229c0ae3722..a0af4b703a8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h @@ -361,7 +361,7 @@ uint32_t nvf0_grhub_code[] = { 0x1fb4f000, 0xf410b4b0, 0xa7f0f01b, - 0xd021f402, + 0xd021f405, /* 0x0223: mmctx_stop */ 0xc82b0ef4, 0xb4b600ab, @@ -528,10 +528,10 @@ uint32_t nvf0_grhub_code[] = { 0x0001d001, 0x17f104bd, 0xf7f00100, - 0x7f21f502, - 0x9121f507, + 0xd721f502, + 0xe921f507, 0x10f7f007, - 0x07de21f5, + 0x083621f5, 0x98000e98, 0x21f5010f, 0x14950150, @@ -574,9 +574,9 @@ uint32_t nvf0_grhub_code[] = { 0xb6800040, 0x1bf40132, 0x00f7f0be, - 0x07de21f5, + 0x083621f5, 0xf500f7f0, - 0xf1077f21, + 0xf107d721, 0xf0010007, 0x01d00203, 0xbd04bd00, @@ -610,8 +610,8 @@ uint32_t nvf0_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x31f40132, - 0xaa21f502, - 0xf094bd09, + 0x0221f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -621,7 +621,7 @@ uint32_t nvf0_grhub_code[] = { 0x0203f037, 0xbd0009d0, 0x0131f404, - 0x09aa21f5, + 0x0a0221f5, 0x99f094bd, 0x0007f106, 0x0203f017, @@ -631,7 +631,7 @@ uint32_t nvf0_grhub_code[] = { 0x12b920f9, 0x0132f402, 0xf50232f4, - 0xfc09aa21, + 0xfc0a0221, 0x0007f120, 0x0203f0c0, 0xbd0002d0, @@ -640,7 +640,7 @@ uint32_t nvf0_grhub_code[] = { 0xf41f23c8, 0x31f40d0b, 0x0232f401, - 0x09aa21f5, + 0x0a0221f5, /* 0x063c: chsw_done */ 0xf10127f0, 0xf0c30007, @@ -654,7 +654,7 @@ uint32_t nvf0_grhub_code[] = { /* 0x0660: main_not_ctx_switch */ 0xf401e4b0, 0xf2b90d1b, - 0x4221f502, + 0x9a21f502, 0x460ef409, /* 0x0670: main_not_ctx_chan */ 0xf402e4b0, @@ -664,8 +664,8 @@ uint32_t nvf0_grhub_code[] = { 0x09d00203, 0xf404bd00, 0x32f40132, - 0xaa21f502, - 0xf094bd09, + 0x0221f502, + 0xf094bd0a, 0x07f10799, 0x03f01700, 0x0009d002, @@ -710,18 +710,40 @@ uint32_t nvf0_grhub_code[] = { /* 0x072b: ih_no_ctxsw */ 0xe40421f4, 0xf40400ab, - 0xb7f1140b, + 0xe7f16c0b, + 0xe3f00708, + 0x6821f440, + 0xf102ffb9, + 0xf0040007, + 0x0fd00203, + 0xf104bd00, + 0xf00704e7, + 0x21f440e3, + 0x02ffb968, + 0x030007f1, + 0xd00203f0, + 0x04bd000f, + 0x9450fec7, + 0xf7f102ee, + 0xf3f00700, + 0x00efbb40, + 0xf16821f4, + 0xf0020007, + 0x0fd00203, + 0xf004bd00, + 0x21f503f7, + 0xb7f1037e, 0xbfb90100, 0x44e7f102, 0x40e3f001, -/* 0x0743: ih_no_fwmthd */ +/* 0x079b: ih_no_fwmthd */ 0xf19d21f4, - 0xbd0104b7, + 0xbd0504b7, 0xb4abffb0, 0xf10f0bf4, 0xf0070007, 0x0bd00303, -/* 0x075b: ih_no_other */ +/* 0x07b3: ih_no_other */ 0xf104bd00, 0xf0010007, 0x0ad00003, @@ -731,19 +753,19 @@ uint32_t nvf0_grhub_code[] = { 0xfc90fca0, 0x0088fe80, 0x32f480fc, -/* 0x077f: ctx_4170s */ +/* 0x07d7: ctx_4170s */ 0xf001f800, 0xffb910f5, 0x70e7f102, 0x40e3f041, 0xf89d21f4, -/* 0x0791: ctx_4170w */ +/* 0x07e9: ctx_4170w */ 0x70e7f100, 0x40e3f041, 0xb96821f4, 0xf4f002ff, 0xf01bf410, -/* 0x07a6: ctx_redswitch */ +/* 0x07fe: ctx_redswitch */ 0xe7f100f8, 0xe5f00200, 0x20e5f040, @@ -751,7 +773,7 @@ uint32_t nvf0_grhub_code[] = { 0xf0850007, 0x0ed00103, 0xf004bd00, -/* 0x07c2: ctx_redswitch_delay */ +/* 0x081a: ctx_redswitch_delay */ 0xf2b608f7, 0xfd1bf401, 0x0400e5f1, @@ -759,7 +781,7 @@ uint32_t nvf0_grhub_code[] = { 0x850007f1, 0xd00103f0, 0x04bd000e, -/* 0x07de: ctx_86c */ +/* 0x0836: ctx_86c */ 0x07f100f8, 0x03f02300, 0x000fd002, @@ -770,17 +792,17 @@ uint32_t nvf0_grhub_code[] = { 0xe7f102ff, 0xe3f0a88c, 0x9d21f441, -/* 0x0806: ctx_mem */ +/* 0x085e: ctx_mem */ 0x07f100f8, 0x03f08400, 0x000fd002, -/* 0x0812: ctx_mem_wait */ +/* 0x086a: ctx_mem_wait */ 0xf7f104bd, 0xf3f08400, 0x00ffcf02, 0xf405fffd, 0x00f8f31b, -/* 0x0824: ctx_load */ +/* 0x087c: ctx_load */ 0x99f094bd, 0x0007f105, 0x0203f037, @@ -797,7 +819,7 @@ uint32_t nvf0_grhub_code[] = { 0x0203f083, 0xbd0002d0, 0x07f7f004, - 0x080621f5, + 0x085e21f5, 0xc00007f1, 0xd00203f0, 0x04bd0002, @@ -852,29 +874,29 @@ uint32_t nvf0_grhub_code[] = { 0x170007f1, 0xd00203f0, 0x04bd0009, -/* 0x0942: ctx_chan */ +/* 0x099a: ctx_chan */ 0x21f500f8, - 0xa7f00824, + 0xa7f0087c, 0xd021f40c, 0xf505f7f0, - 0xf8080621, -/* 0x0955: ctx_mmio_exec */ + 0xf8085e21, +/* 0x09ad: ctx_mmio_exec */ 0x41039800, 0x810007f1, 0xd00203f0, 0x04bd0003, -/* 0x0966: ctx_mmio_loop */ +/* 0x09be: ctx_mmio_loop */ 0x34c434bd, 0x0f1bf4ff, 0x020057f1, 0xfa0653f0, 0x03f80535, -/* 0x0978: ctx_mmio_pull */ +/* 0x09d0: ctx_mmio_pull */ 0x98804e98, 0x21f4814f, 0x0830b69d, 0xf40112b6, -/* 0x098a: ctx_mmio_done */ +/* 0x09e2: ctx_mmio_done */ 0x0398df1b, 0x0007f116, 0x0203f081, @@ -883,30 +905,30 @@ uint32_t nvf0_grhub_code[] = { 0x010017f1, 0xfa0613f0, 0x03f80601, -/* 0x09aa: ctx_xfer */ +/* 0x0a02: ctx_xfer */ 0xe7f000f8, 0x0007f104, 0x0303f002, 0xbd000ed0, -/* 0x09b9: ctx_xfer_idle */ +/* 0x0a11: ctx_xfer_idle */ 0x00e7f104, 0x03e3f000, 0xf100eecf, 0xf42000e4, 0x11f4f21b, 0x0d02f406, -/* 0x09d0: ctx_xfer_pre */ +/* 0x0a28: ctx_xfer_pre */ 0xf510f7f0, - 0xf407de21, -/* 0x09da: ctx_xfer_pre_load */ + 0xf4083621, +/* 0x0a32: ctx_xfer_pre_load */ 0xf7f01c11, - 0x7f21f502, - 0x9121f507, - 0xa621f507, + 0xd721f502, + 0xe921f507, + 0xfe21f507, 0xf5f4bd07, - 0xf5077f21, -/* 0x09f3: ctx_xfer_exec */ - 0x98082421, + 0xf507d721, +/* 0x0a4b: ctx_xfer_exec */ + 0x98087c21, 0x24bd1601, 0x050007f1, 0xd00103f0, @@ -941,21 +963,21 @@ uint32_t nvf0_grhub_code[] = { 0xa7f01301, 0xd021f40c, 0xf505f7f0, - 0xf4080621, -/* 0x0a82: ctx_xfer_post */ + 0xf4085e21, +/* 0x0ada: ctx_xfer_post */ 0xf7f02e02, - 0x7f21f502, + 0xd721f502, 0xf5f4bd07, - 0xf507de21, + 0xf5083621, 0xf5027f21, - 0xbd079121, - 0x7f21f5f4, + 0xbd07e921, + 0xd721f5f4, 0x1011f407, 0xfd400198, 0x0bf40511, - 0x5521f507, -/* 0x0aad: ctx_xfer_no_post_mmio */ -/* 0x0aad: ctx_xfer_done */ + 0xad21f507, +/* 0x0b05: ctx_xfer_no_post_mmio */ +/* 0x0b05: ctx_xfer_done */ 0x0000f809, 0x00000000, 0x00000000, @@ -977,4 +999,46 @@ uint32_t nvf0_grhub_code[] = { 0x00000000, 0x00000000, 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc index 6ffe28307db..2a0b0f84429 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc @@ -30,6 +30,12 @@ #define GK110 0xf0 #define GK208 0x108 +#define NV_PGRAPH_TRAPPED_ADDR 0x400704 +#define NV_PGRAPH_TRAPPED_DATA_LO 0x400708 +#define NV_PGRAPH_TRAPPED_DATA_HI 0x40070c + +#define NV_PGRAPH_FE_OBJECT_TABLE(n) ((n) * 4 + 0x400700) + #define NV_PGRAPH_FECS_INTR_ACK 0x409004 #define NV_PGRAPH_FECS_INTR 0x409008 #define NV_PGRAPH_FECS_INTR_FWMTHD 0x00000400 @@ -132,6 +138,7 @@ #define NV_PGRAPH_GPCX_GPCCS_FIFO_CMD 0x41a068 #define NV_PGRAPH_GPCX_GPCCS_FIFO_ACK 0x41a074 #define NV_PGRAPH_GPCX_GPCCS_UNITS 0x41a608 +#define NV_PGRAPH_GPCX_GPCCS_CAPS 0x41a108 #define NV_PGRAPH_GPCX_GPCCS_RED_SWITCH 0x41a614 #define NV_PGRAPH_GPCX_GPCCS_RED_SWITCH_UNK11 0x00000800 #define NV_PGRAPH_GPCX_GPCCS_RED_SWITCH_ENABLE 0x00000200 diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h index fd1d380de09..1718ae4e822 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/os.h @@ -3,5 +3,6 @@ #define E_BAD_COMMAND 0x00000001 #define E_CMD_OVERFLOW 0x00000002 +#define E_BAD_FWMTHD 0x00000003 #endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c b/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c new file mode 100644 index 00000000000..83048a56430 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "nvc0.h" +#include "ctxnvc0.h" + +static struct nouveau_oclass +gk20a_graph_sclass[] = { + { 0x902d, &nouveau_object_ofuncs }, + { 0xa040, &nouveau_object_ofuncs }, + { 0xa297, &nouveau_object_ofuncs }, + { 0xa0c0, &nouveau_object_ofuncs }, + {} +}; + +struct nouveau_oclass * +gk20a_graph_oclass = &(struct nvc0_graph_oclass) { + .base.handle = NV_ENGINE(GR, 0xea), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_ctor, + .dtor = nvc0_graph_dtor, + .init = nve4_graph_init, + .fini = nve4_graph_fini, + }, + .cclass = &gk20a_grctx_oclass, + .sclass = gk20a_graph_sclass, + .mmio = nve4_graph_pack_mmio, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c b/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c new file mode 100644 index 00000000000..21c5f31d607 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/graph/gm107.c @@ -0,0 +1,465 @@ +/* + * 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 <subdev/bios.h> +#include <subdev/bios/P0260.h> + +#include "nvc0.h" +#include "ctxnvc0.h" + +/******************************************************************************* + * Graphics object classes + ******************************************************************************/ + +static struct nouveau_oclass +gm107_graph_sclass[] = { + { 0x902d, &nouveau_object_ofuncs }, + { 0xa140, &nouveau_object_ofuncs }, + { 0xb097, &nouveau_object_ofuncs }, + { 0xb0c0, &nouveau_object_ofuncs }, + {} +}; + +/******************************************************************************* + * PGRAPH register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +gm107_graph_init_main_0[] = { + { 0x400080, 1, 0x04, 0x003003c2 }, + { 0x400088, 1, 0x04, 0x0001bfe7 }, + { 0x40008c, 1, 0x04, 0x00060000 }, + { 0x400090, 1, 0x04, 0x00000030 }, + { 0x40013c, 1, 0x04, 0x003901f3 }, + { 0x400140, 1, 0x04, 0x00000100 }, + { 0x400144, 1, 0x04, 0x00000000 }, + { 0x400148, 1, 0x04, 0x00000110 }, + { 0x400138, 1, 0x04, 0x00000000 }, + { 0x400130, 2, 0x04, 0x00000000 }, + { 0x400124, 1, 0x04, 0x00000002 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_ds_0[] = { + { 0x405844, 1, 0x04, 0x00ffffff }, + { 0x405850, 1, 0x04, 0x00000000 }, + { 0x405900, 1, 0x04, 0x00000000 }, + { 0x405908, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_scc_0[] = { + { 0x40803c, 1, 0x04, 0x00000010 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_sked_0[] = { + { 0x407010, 1, 0x04, 0x00000000 }, + { 0x407040, 1, 0x04, 0x40440424 }, + { 0x407048, 1, 0x04, 0x0000000a }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_prop_0[] = { + { 0x418408, 1, 0x04, 0x00000000 }, + { 0x4184a0, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_setup_1[] = { + { 0x4188c8, 2, 0x04, 0x00000000 }, + { 0x4188d0, 1, 0x04, 0x00010000 }, + { 0x4188d4, 1, 0x04, 0x00010201 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_zcull_0[] = { + { 0x418910, 1, 0x04, 0x00010001 }, + { 0x418914, 1, 0x04, 0x00000301 }, + { 0x418918, 1, 0x04, 0x00800000 }, + { 0x418930, 2, 0x04, 0x00000000 }, + { 0x418980, 1, 0x04, 0x77777770 }, + { 0x418984, 3, 0x04, 0x77777777 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_gpc_unk_1[] = { + { 0x418d00, 1, 0x04, 0x00000000 }, + { 0x418f00, 1, 0x04, 0x00000400 }, + { 0x418f08, 1, 0x04, 0x00000000 }, + { 0x418e08, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_tpccs_0[] = { + { 0x419dc4, 1, 0x04, 0x00000000 }, + { 0x419dc8, 1, 0x04, 0x00000501 }, + { 0x419dd0, 1, 0x04, 0x00000000 }, + { 0x419dd4, 1, 0x04, 0x00000100 }, + { 0x419dd8, 1, 0x04, 0x00000001 }, + { 0x419ddc, 1, 0x04, 0x00000002 }, + { 0x419de0, 1, 0x04, 0x00000001 }, + { 0x419d0c, 1, 0x04, 0x00000000 }, + { 0x419d10, 1, 0x04, 0x00000014 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_tex_0[] = { + { 0x419ab0, 1, 0x04, 0x00000000 }, + { 0x419ab8, 1, 0x04, 0x000000e7 }, + { 0x419abc, 1, 0x04, 0x00000000 }, + { 0x419acc, 1, 0x04, 0x000000ff }, + { 0x419ac0, 1, 0x04, 0x00000000 }, + { 0x419aa8, 2, 0x04, 0x00000000 }, + { 0x419ad0, 2, 0x04, 0x00000000 }, + { 0x419ae0, 2, 0x04, 0x00000000 }, + { 0x419af0, 4, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_pe_0[] = { + { 0x419900, 1, 0x04, 0x000000ff }, + { 0x41980c, 1, 0x04, 0x00000010 }, + { 0x419844, 1, 0x04, 0x00000000 }, + { 0x419838, 1, 0x04, 0x000000ff }, + { 0x419850, 1, 0x04, 0x00000004 }, + { 0x419854, 2, 0x04, 0x00000000 }, + { 0x419894, 3, 0x04, 0x00100401 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_l1c_0[] = { + { 0x419c98, 1, 0x04, 0x00000000 }, + { 0x419cc0, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_sm_0[] = { + { 0x419e30, 1, 0x04, 0x000000ff }, + { 0x419e00, 1, 0x04, 0x00000000 }, + { 0x419ea0, 1, 0x04, 0x00000000 }, + { 0x419ee4, 1, 0x04, 0x00000000 }, + { 0x419ea4, 1, 0x04, 0x00000100 }, + { 0x419ea8, 1, 0x04, 0x01000000 }, + { 0x419ee8, 1, 0x04, 0x00000091 }, + { 0x419eb4, 1, 0x04, 0x00000000 }, + { 0x419ebc, 2, 0x04, 0x00000000 }, + { 0x419edc, 1, 0x04, 0x000c1810 }, + { 0x419ed8, 1, 0x04, 0x00000000 }, + { 0x419ee0, 1, 0x04, 0x00000000 }, + { 0x419f74, 1, 0x04, 0x00005155 }, + { 0x419f80, 4, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_l1c_1[] = { + { 0x419ccc, 2, 0x04, 0x00000000 }, + { 0x419c80, 1, 0x04, 0x3f006022 }, + { 0x419c88, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_pes_0[] = { + { 0x41be50, 1, 0x04, 0x000000ff }, + { 0x41be04, 1, 0x04, 0x00000000 }, + { 0x41be08, 1, 0x04, 0x00000004 }, + { 0x41be0c, 1, 0x04, 0x00000008 }, + { 0x41be10, 1, 0x04, 0x0e3b8bc7 }, + { 0x41be14, 2, 0x04, 0x00000000 }, + { 0x41be3c, 5, 0x04, 0x00100401 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_wwdx_0[] = { + { 0x41bfd4, 1, 0x04, 0x00800000 }, + { 0x41bfdc, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_cbm_0[] = { + { 0x41becc, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_be_0[] = { + { 0x408890, 1, 0x04, 0x000000ff }, + { 0x40880c, 1, 0x04, 0x00000000 }, + { 0x408850, 1, 0x04, 0x00000004 }, + { 0x408878, 1, 0x04, 0x00c81603 }, + { 0x40887c, 1, 0x04, 0x80543432 }, + { 0x408880, 1, 0x04, 0x0010581e }, + { 0x408884, 1, 0x04, 0x00001205 }, + { 0x408974, 1, 0x04, 0x000000ff }, + { 0x408910, 9, 0x04, 0x00000000 }, + { 0x408950, 1, 0x04, 0x00000000 }, + { 0x408954, 1, 0x04, 0x0000ffff }, + { 0x408958, 1, 0x04, 0x00000034 }, + { 0x40895c, 1, 0x04, 0x8531a003 }, + { 0x408960, 1, 0x04, 0x0561985a }, + { 0x408964, 1, 0x04, 0x04e15c4f }, + { 0x408968, 1, 0x04, 0x02808833 }, + { 0x40896c, 1, 0x04, 0x01f02438 }, + { 0x408970, 1, 0x04, 0x00012c00 }, + { 0x408984, 1, 0x04, 0x00000000 }, + { 0x408988, 1, 0x04, 0x08040201 }, + { 0x40898c, 1, 0x04, 0x80402010 }, + {} +}; + +static const struct nvc0_graph_init +gm107_graph_init_sm_1[] = { + { 0x419e5c, 1, 0x04, 0x00000000 }, + { 0x419e58, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +gm107_graph_pack_mmio[] = { + { gm107_graph_init_main_0 }, + { nvf0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvc0_graph_init_pd_0 }, + { gm107_graph_init_ds_0 }, + { gm107_graph_init_scc_0 }, + { gm107_graph_init_sked_0 }, + { nvf0_graph_init_cwd_0 }, + { gm107_graph_init_prop_0 }, + { nv108_graph_init_gpc_unk_0 }, + { nvc0_graph_init_setup_0 }, + { nvc0_graph_init_crstr_0 }, + { gm107_graph_init_setup_1 }, + { gm107_graph_init_zcull_0 }, + { nvc0_graph_init_gpm_0 }, + { gm107_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { gm107_graph_init_tpccs_0 }, + { gm107_graph_init_tex_0 }, + { gm107_graph_init_pe_0 }, + { gm107_graph_init_l1c_0 }, + { nvc0_graph_init_mpc_0 }, + { gm107_graph_init_sm_0 }, + { gm107_graph_init_l1c_1 }, + { gm107_graph_init_pes_0 }, + { gm107_graph_init_wwdx_0 }, + { gm107_graph_init_cbm_0 }, + { gm107_graph_init_be_0 }, + { gm107_graph_init_sm_1 }, + {} +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + +static void +gm107_graph_init_bios(struct nvc0_graph_priv *priv) +{ + static const struct { + u32 ctrl; + u32 data; + } regs[] = { + { 0x419ed8, 0x419ee0 }, + { 0x419ad0, 0x419ad4 }, + { 0x419ae0, 0x419ae4 }, + { 0x419af0, 0x419af4 }, + { 0x419af8, 0x419afc }, + }; + struct nouveau_bios *bios = nouveau_bios(priv); + struct nvbios_P0260E infoE; + struct nvbios_P0260X infoX; + int E = -1, X; + u8 ver, hdr; + + while (nvbios_P0260Ep(bios, ++E, &ver, &hdr, &infoE)) { + if (X = -1, E < ARRAY_SIZE(regs)) { + nv_wr32(priv, regs[E].ctrl, infoE.data); + while (nvbios_P0260Xp(bios, ++X, &ver, &hdr, &infoX)) + nv_wr32(priv, regs[E].data, infoX.data); + } + } +} + +int +gm107_graph_init(struct nouveau_object *object) +{ + struct nvc0_graph_oclass *oclass = (void *)object->oclass; + struct nvc0_graph_priv *priv = (void *)object; + const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total); + u32 data[TPC_MAX / 8] = {}; + u8 tpcnr[GPC_MAX]; + int gpc, tpc, ppc, rop; + int ret, i; + + ret = nouveau_graph_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x0890), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x0894), 0x00000000); + nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8); + nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8); + + nvc0_graph_mmio(priv, oclass->mmio); + + gm107_graph_init_bios(priv); + + nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001); + + memset(data, 0x00, sizeof(data)); + memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); + for (i = 0, gpc = -1; i < priv->tpc_total; i++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpcnr[gpc]); + tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; + + data[i / 8] |= tpc << ((i % 8) * 4); + } + + nv_wr32(priv, GPC_BCAST(0x0980), data[0]); + nv_wr32(priv, GPC_BCAST(0x0984), data[1]); + nv_wr32(priv, GPC_BCAST(0x0988), data[2]); + nv_wr32(priv, GPC_BCAST(0x098c), data[3]); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(priv, GPC_UNIT(gpc, 0x0914), + priv->magic_not_rop_nr << 8 | priv->tpc_nr[gpc]); + nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | + priv->tpc_total); + nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); + } + + nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918); + nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); + + nv_wr32(priv, 0x400500, 0x00010001); + + nv_wr32(priv, 0x400100, 0xffffffff); + nv_wr32(priv, 0x40013c, 0xffffffff); + nv_wr32(priv, 0x400124, 0x00000002); + nv_wr32(priv, 0x409c24, 0x000e0000); + + nv_wr32(priv, 0x404000, 0xc0000000); + nv_wr32(priv, 0x404600, 0xc0000000); + nv_wr32(priv, 0x408030, 0xc0000000); + nv_wr32(priv, 0x404490, 0xc0000000); + nv_wr32(priv, 0x406018, 0xc0000000); + nv_wr32(priv, 0x407020, 0x40000000); + nv_wr32(priv, 0x405840, 0xc0000000); + nv_wr32(priv, 0x405844, 0x00ffffff); + nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + for (ppc = 0; ppc < 2 /* priv->ppc_nr[gpc] */; ppc++) + nv_wr32(priv, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000); + nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000); + for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) { + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe); + nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005); + } + nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff); + nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff); + } + + for (rop = 0; rop < priv->rop_nr; rop++) { + nv_wr32(priv, ROP_UNIT(rop, 0x144), 0x40000000); + nv_wr32(priv, ROP_UNIT(rop, 0x070), 0x40000000); + nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff); + nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff); + } + + nv_wr32(priv, 0x400108, 0xffffffff); + nv_wr32(priv, 0x400138, 0xffffffff); + nv_wr32(priv, 0x400118, 0xffffffff); + nv_wr32(priv, 0x400130, 0xffffffff); + nv_wr32(priv, 0x40011c, 0xffffffff); + nv_wr32(priv, 0x400134, 0xffffffff); + + nv_wr32(priv, 0x400054, 0x2c350f63); + return nvc0_graph_init_ctxctl(priv); +} + +#include "fuc/hubgm107.fuc5.h" + +static struct nvc0_graph_ucode +gm107_graph_fecs_ucode = { + .code.data = gm107_grhub_code, + .code.size = sizeof(gm107_grhub_code), + .data.data = gm107_grhub_data, + .data.size = sizeof(gm107_grhub_data), +}; + +#include "fuc/gpcgm107.fuc5.h" + +static struct nvc0_graph_ucode +gm107_graph_gpccs_ucode = { + .code.data = gm107_grgpc_code, + .code.size = sizeof(gm107_grgpc_code), + .data.data = gm107_grgpc_data, + .data.size = sizeof(gm107_grgpc_data), +}; + +struct nouveau_oclass * +gm107_graph_oclass = &(struct nvc0_graph_oclass) { + .base.handle = NV_ENGINE(GR, 0x07), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_graph_ctor, + .dtor = nvc0_graph_dtor, + .init = gm107_graph_init, + .fini = _nouveau_graph_fini, + }, + .cclass = &gm107_grctx_oclass, + .sclass = gm107_graph_sclass, + .mmio = gm107_graph_pack_mmio, + .fecs.ucode = 0 ? &gm107_graph_fecs_ucode : NULL, + .gpccs.ucode = &gm107_graph_gpccs_ucode, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c index e1af65ead37..00ea1a08982 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv108.c @@ -23,6 +23,7 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* * Graphics object classes @@ -38,11 +39,11 @@ nv108_graph_sclass[] = { }; /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -static struct nvc0_graph_init -nv108_graph_init_regs[] = { +static const struct nvc0_graph_init +nv108_graph_init_main_0[] = { { 0x400080, 1, 0x04, 0x003083c2 }, { 0x400088, 1, 0x04, 0x0001bfe7 }, { 0x40008c, 1, 0x04, 0x00000000 }, @@ -57,66 +58,46 @@ nv108_graph_init_regs[] = { {} }; -struct nvc0_graph_init -nv108_graph_init_unk58xx[] = { +static const struct nvc0_graph_init +nv108_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, { 0x405900, 1, 0x04, 0x00000000 }, { 0x405908, 1, 0x04, 0x00000000 }, - { 0x405928, 1, 0x04, 0x00000000 }, - { 0x40592c, 1, 0x04, 0x00000000 }, + { 0x405928, 2, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nv108_graph_init_gpc[] = { - { 0x418408, 1, 0x04, 0x00000000 }, - { 0x4184a0, 3, 0x04, 0x00000000 }, +const struct nvc0_graph_init +nv108_graph_init_gpc_unk_0[] = { { 0x418604, 1, 0x04, 0x00000000 }, { 0x418680, 1, 0x04, 0x00000000 }, { 0x418714, 1, 0x04, 0x00000000 }, { 0x418384, 2, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nv108_graph_init_setup_1[] = { { 0x4188c8, 2, 0x04, 0x00000000 }, { 0x4188d0, 1, 0x04, 0x00010000 }, { 0x4188d4, 1, 0x04, 0x00000201 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, - { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c64, 2, 0x04, 0x00000000 }, - { 0x418c88, 1, 0x04, 0x00000000 }, - { 0x418cb4, 2, 0x04, 0x00000000 }, - { 0x418d00, 1, 0x04, 0x00000000 }, - { 0x418d28, 2, 0x04, 0x00000000 }, - { 0x418f00, 1, 0x04, 0x00000400 }, - { 0x418f08, 1, 0x04, 0x00000000 }, - { 0x418f20, 2, 0x04, 0x00000000 }, - { 0x418e00, 1, 0x04, 0x00000000 }, - { 0x418e08, 1, 0x04, 0x00000000 }, - { 0x418e1c, 2, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nv108_graph_init_tpc[] = { - { 0x419d0c, 1, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, +static const struct nvc0_graph_init +nv108_graph_init_tex_0[] = { { 0x419ab0, 1, 0x04, 0x00000000 }, { 0x419ac8, 1, 0x04, 0x00000000 }, { 0x419ab8, 1, 0x04, 0x000000e7 }, { 0x419abc, 2, 0x04, 0x00000000 }, { 0x419ab4, 1, 0x04, 0x00000000 }, { 0x419aa8, 2, 0x04, 0x00000000 }, - { 0x41980c, 1, 0x04, 0x00000010 }, - { 0x419844, 1, 0x04, 0x00000000 }, - { 0x419850, 1, 0x04, 0x00000004 }, - { 0x419854, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nv108_graph_init_l1c_0[] = { { 0x419c98, 1, 0x04, 0x00000000 }, { 0x419ca8, 1, 0x04, 0x00000000 }, { 0x419cb0, 1, 0x04, 0x01000000 }, @@ -127,22 +108,47 @@ nv108_graph_init_tpc[] = { { 0x419cc0, 2, 0x04, 0x00000000 }, { 0x419c80, 1, 0x04, 0x00000230 }, { 0x419ccc, 2, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, - { 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, 0x00003234 }, - { 0x419f74, 1, 0x04, 0x00015555 }, - { 0x419f80, 4, 0x04, 0x00000000 }, {} }; +static const struct nvc0_graph_pack +nv108_graph_pack_mmio[] = { + { nv108_graph_init_main_0 }, + { nvf0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvd9_graph_init_pd_0 }, + { nv108_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nvf0_graph_init_sked_0 }, + { nvf0_graph_init_cwd_0 }, + { nvd9_graph_init_prop_0 }, + { nv108_graph_init_gpc_unk_0 }, + { nvc0_graph_init_setup_0 }, + { nvc0_graph_init_crstr_0 }, + { nv108_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 }, + { nv108_graph_init_tex_0 }, + { nve4_graph_init_pe_0 }, + { nv108_graph_init_l1c_0 }, + { nvc0_graph_init_mpc_0 }, + { nvf0_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 + ******************************************************************************/ + static int nv108_graph_fini(struct nouveau_object *object, bool suspend) { @@ -180,25 +186,6 @@ nv108_graph_fini(struct nouveau_object *object, bool suspend) return nouveau_graph_fini(&priv->base, suspend); } -static struct nvc0_graph_init * -nv108_graph_init_mmio[] = { - nv108_graph_init_regs, - nvf0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvd9_graph_init_unk64xx, - nv108_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvf0_graph_init_unk70xx, - nvf0_graph_init_unk5bxx, - nv108_graph_init_gpc, - nv108_graph_init_tpc, - nve4_graph_init_unk, - nve4_graph_init_unk88xx, - NULL -}; - #include "fuc/hubnv108.fuc5.h" static struct nvc0_graph_ucode @@ -230,7 +217,7 @@ nv108_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nv108_grctx_oclass, .sclass = nv108_graph_sclass, - .mmio = nv108_graph_init_mmio, + .mmio = nv108_graph_pack_mmio, .fecs.ucode = &nv108_graph_fecs_ucode, .gpccs.ucode = &nv108_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c index b2455931590..d145e080899 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c @@ -349,7 +349,7 @@ nv20_graph_init(struct nouveau_object *object) nv_wr32(priv, NV10_PGRAPH_SURFACE, tmp); /* begin RAM config */ - vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1; + vramsz = nv_device_resource_len(nv_device(priv), 0) - 1; nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200)); nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204)); nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 193a5de1b48..6477fbf6a55 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -484,7 +484,7 @@ nv40_graph_init(struct nouveau_object *object) engine->tile_prog(engine, i); /* begin RAM config */ - vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1; + vramsz = nv_device_resource_len(nv_device(priv), 0) - 1; switch (nv_device(priv)->chipset) { case 0x40: nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200)); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c index 30ed19c52e0..20665c21d80 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c @@ -197,34 +197,35 @@ static const struct nouveau_bitfield nv50_pgraph_status[] = { { 0x00000080, "UNK7" }, { 0x00000100, "CTXPROG" }, { 0x00000200, "VFETCH" }, - { 0x00000400, "CCACHE_UNK4" }, - { 0x00000800, "STRMOUT_GSCHED_UNK5" }, - { 0x00001000, "UNK14XX" }, - { 0x00002000, "UNK24XX_CSCHED" }, - { 0x00004000, "UNK1CXX" }, + { 0x00000400, "CCACHE_PREGEOM" }, + { 0x00000800, "STRMOUT_VATTR_POSTGEOM" }, + { 0x00001000, "VCLIP" }, + { 0x00002000, "RATTR_APLANE" }, + { 0x00004000, "TRAST" }, { 0x00008000, "CLIPID" }, { 0x00010000, "ZCULL" }, { 0x00020000, "ENG2D" }, - { 0x00040000, "UNK34XX" }, - { 0x00080000, "TPRAST" }, - { 0x00100000, "TPROP" }, - { 0x00200000, "TEX" }, - { 0x00400000, "TPVP" }, - { 0x00800000, "MP" }, + { 0x00040000, "RMASK" }, + { 0x00080000, "TPC_RAST" }, + { 0x00100000, "TPC_PROP" }, + { 0x00200000, "TPC_TEX" }, + { 0x00400000, "TPC_GEOM" }, + { 0x00800000, "TPC_MP" }, { 0x01000000, "ROP" }, {} }; static const char *const nv50_pgraph_vstatus_0[] = { - "VFETCH", "CCACHE", "UNK4", "UNK5", "GSCHED", "STRMOUT", "UNK14XX", NULL + "VFETCH", "CCACHE", "PREGEOM", "POSTGEOM", "VATTR", "STRMOUT", "VCLIP", + NULL }; static const char *const nv50_pgraph_vstatus_1[] = { - "TPRAST", "TPROP", "TEXTURE", "TPVP", "MP", NULL + "TPC_RAST", "TPC_PROP", "TPC_TEX", "TPC_GEOM", "TPC_MP", NULL }; static const char *const nv50_pgraph_vstatus_2[] = { - "UNK24XX", "CSCHED", "UNK1CXX", "CLIPID", "ZCULL", "ENG2D", "UNK34XX", + "RATTR", "APLANE", "TRAST", "CLIPID", "ZCULL", "ENG2D", "RMASK", "ROP", NULL }; @@ -329,6 +330,15 @@ static const struct nouveau_bitfield nv50_mpc_traps[] = { {} }; +static const struct nouveau_bitfield nv50_tex_traps[] = { + { 0x00000001, "" }, /* any bit set? */ + { 0x00000002, "FAULT" }, + { 0x00000004, "STORAGE_TYPE_MISMATCH" }, + { 0x00000008, "LINEAR_MISMATCH" }, + { 0x00000020, "WRONG_MEMTYPE" }, + {} +}; + static const struct nouveau_bitfield nv50_graph_trap_m2mf[] = { { 0x00000001, "NOTIFY" }, { 0x00000002, "IN" }, @@ -531,6 +541,13 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) nv_error(priv, "\t0x%08x: 0x%08x\n", r, nv_rd32(priv, r)); + if (ustatus) { + nv_error(priv, "%s - TP%d:", name, i); + nouveau_bitfield_print(nv50_tex_traps, + ustatus); + pr_cont("\n"); + ustatus = 0; + } } break; case 7: /* MP error */ @@ -539,7 +556,7 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old, ustatus &= ~0x04030000; } if (ustatus && display) { - nv_error("%s - TP%d:", name, i); + nv_error(priv, "%s - TP%d:", name, i); nouveau_bitfield_print(nv50_mpc_traps, ustatus); pr_cont("\n"); ustatus = 0; @@ -884,7 +901,7 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nvaf_graph_sclass; break; - }; + } /* unfortunate hw bug workaround... */ if (nv_device(priv)->chipset != 0x50 && @@ -959,7 +976,6 @@ nv50_graph_init(struct nouveau_object *object) break; case 0xa0: default: - nv_wr32(priv, 0x402cc0, 0x00000000); if (nv_device(priv)->chipset == 0xa0 || nv_device(priv)->chipset == 0xaa || nv_device(priv)->chipset == 0xac) { @@ -974,10 +990,10 @@ nv50_graph_init(struct nouveau_object *object) /* zero out zcull regions */ for (i = 0; i < 8; i++) { - nv_wr32(priv, 0x402c20 + (i * 8), 0x00000000); - nv_wr32(priv, 0x402c24 + (i * 8), 0x00000000); - nv_wr32(priv, 0x402c28 + (i * 8), 0x00000000); - nv_wr32(priv, 0x402c2c + (i * 8), 0x00000000); + nv_wr32(priv, 0x402c20 + (i * 0x10), 0x00000000); + nv_wr32(priv, 0x402c24 + (i * 0x10), 0x00000000); + nv_wr32(priv, 0x402c28 + (i * 0x10), 0x00000000); + nv_wr32(priv, 0x402c2c + (i * 0x10), 0x00000000); } return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index a73ab209ea8..aa083891635 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -23,6 +23,7 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* * Graphics object classes @@ -146,11 +147,11 @@ nvc0_graph_context_dtor(struct nouveau_object *object) } /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -struct nvc0_graph_init -nvc0_graph_init_regs[] = { +const struct nvc0_graph_init +nvc0_graph_init_main_0[] = { { 0x400080, 1, 0x04, 0x003083c2 }, { 0x400088, 1, 0x04, 0x00006fe7 }, { 0x40008c, 1, 0x04, 0x00000000 }, @@ -165,95 +166,170 @@ nvc0_graph_init_regs[] = { {} }; -struct nvc0_graph_init -nvc0_graph_init_unk40xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_fe_0[] = { { 0x40415c, 1, 0x04, 0x00000000 }, { 0x404170, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_graph_init_unk44xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_pri_0[] = { { 0x404488, 2, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_graph_init_unk78xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_rstr2d_0[] = { { 0x407808, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_graph_init_unk60xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_pd_0[] = { { 0x406024, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_graph_init_unk58xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, { 0x405908, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_graph_init_unk80xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_scc_0[] = { { 0x40803c, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvc0_graph_init_gpc[] = { +const struct nvc0_graph_init +nvc0_graph_init_prop_0[] = { { 0x4184a0, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_gpc_unk_0[] = { { 0x418604, 1, 0x04, 0x00000000 }, { 0x418680, 1, 0x04, 0x00000000 }, { 0x418714, 1, 0x04, 0x80000000 }, { 0x418384, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_setup_0[] = { { 0x418814, 3, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_crstr_0[] = { { 0x418b04, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_setup_1[] = { { 0x4188c8, 1, 0x04, 0x80000000 }, { 0x4188cc, 1, 0x04, 0x00000000 }, { 0x4188d0, 1, 0x04, 0x00010000 }, { 0x4188d4, 1, 0x04, 0x00000001 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_zcull_0[] = { { 0x418910, 1, 0x04, 0x00010001 }, { 0x418914, 1, 0x04, 0x00000301 }, { 0x418918, 1, 0x04, 0x00800000 }, { 0x418980, 1, 0x04, 0x77777770 }, { 0x418984, 3, 0x04, 0x77777777 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_gpm_0[] = { { 0x418c04, 1, 0x04, 0x00000000 }, { 0x418c88, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_gpc_unk_1[] = { { 0x418d00, 1, 0x04, 0x00000000 }, { 0x418f08, 1, 0x04, 0x00000000 }, { 0x418e00, 1, 0x04, 0x00000050 }, { 0x418e08, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_gcc_0[] = { { 0x41900c, 1, 0x04, 0x00000000 }, { 0x419018, 1, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvc0_graph_init_tpc[] = { +const struct nvc0_graph_init +nvc0_graph_init_tpccs_0[] = { { 0x419d08, 2, 0x04, 0x00000000 }, { 0x419d10, 1, 0x04, 0x00000014 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_tex_0[] = { { 0x419ab0, 1, 0x04, 0x00000000 }, { 0x419ab8, 1, 0x04, 0x000000e7 }, { 0x419abc, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_pe_0[] = { { 0x41980c, 3, 0x04, 0x00000000 }, { 0x419844, 1, 0x04, 0x00000000 }, { 0x41984c, 1, 0x04, 0x00005bc5 }, { 0x419850, 4, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_l1c_0[] = { { 0x419c98, 1, 0x04, 0x00000000 }, { 0x419ca8, 1, 0x04, 0x80000000 }, { 0x419cb4, 1, 0x04, 0x00000000 }, { 0x419cb8, 1, 0x04, 0x00008bf4 }, { 0x419cbc, 1, 0x04, 0x28137606 }, { 0x419cc0, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_wwdx_0[] = { { 0x419bd4, 1, 0x04, 0x00800000 }, { 0x419bdc, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_tpccs_1[] = { { 0x419d2c, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_mpc_0[] = { { 0x419c0c, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvc0_graph_init_sm_0[] = { { 0x419e00, 1, 0x04, 0x00000000 }, { 0x419ea0, 1, 0x04, 0x00000000 }, { 0x419ea4, 1, 0x04, 0x00000100 }, @@ -270,8 +346,8 @@ nvc0_graph_init_tpc[] = { {} }; -struct nvc0_graph_init -nvc0_graph_init_unk88xx[] = { +const struct nvc0_graph_init +nvc0_graph_init_be_0[] = { { 0x40880c, 1, 0x04, 0x00000000 }, { 0x408910, 9, 0x04, 0x00000000 }, { 0x408950, 1, 0x04, 0x00000000 }, @@ -282,18 +358,64 @@ nvc0_graph_init_unk88xx[] = { {} }; -struct nvc0_graph_init -nvc0_graph_tpc_0[] = { - { 0x50405c, 1, 0x04, 0x00000001 }, +const struct nvc0_graph_init +nvc0_graph_init_fe_1[] = { + { 0x4040f0, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc0_graph_init_pe_1[] = { + { 0x419880, 1, 0x04, 0x00000002 }, {} }; +static const struct nvc0_graph_pack +nvc0_graph_pack_mmio[] = { + { nvc0_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvc0_graph_init_pd_0 }, + { nvc0_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nvc0_graph_init_prop_0 }, + { nvc0_graph_init_gpc_unk_0 }, + { nvc0_graph_init_setup_0 }, + { nvc0_graph_init_crstr_0 }, + { nvc0_graph_init_setup_1 }, + { nvc0_graph_init_zcull_0 }, + { nvc0_graph_init_gpm_0 }, + { nvc0_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nvc0_graph_init_tpccs_0 }, + { nvc0_graph_init_tex_0 }, + { nvc0_graph_init_pe_0 }, + { nvc0_graph_init_l1c_0 }, + { nvc0_graph_init_wwdx_0 }, + { nvc0_graph_init_tpccs_1 }, + { nvc0_graph_init_mpc_0 }, + { nvc0_graph_init_sm_0 }, + { nvc0_graph_init_be_0 }, + { nvc0_graph_init_fe_1 }, + { nvc0_graph_init_pe_1 }, + {} +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + void -nvc0_graph_mmio(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init) +nvc0_graph_mmio(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p) { - for (; init && init->count; init++) { - u32 addr = init->addr, i; - for (i = 0; i < init->count; i++) { + const struct nvc0_graph_pack *pack; + const struct nvc0_graph_init *init; + + pack_for_each_init(init, pack, p) { + u32 next = init->addr + init->count * init->pitch; + u32 addr = init->addr; + while (addr < next) { nv_wr32(priv, addr, init->data); addr += init->pitch; } @@ -301,49 +423,53 @@ nvc0_graph_mmio(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init) } void -nvc0_graph_icmd(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init) +nvc0_graph_icmd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p) { - u32 addr, data; - int i, j; + const struct nvc0_graph_pack *pack; + const struct nvc0_graph_init *init; + u32 data = 0; nv_wr32(priv, 0x400208, 0x80000000); - for (i = 0; init->count; init++, i++) { - if (!i || data != init->data) { + + pack_for_each_init(init, pack, p) { + u32 next = init->addr + init->count * init->pitch; + u32 addr = init->addr; + + if ((pack == p && init == p->init) || data != init->data) { nv_wr32(priv, 0x400204, init->data); data = init->data; } - addr = init->addr; - for (j = 0; j < init->count; j++) { + while (addr < next) { nv_wr32(priv, 0x400200, addr); + nv_wait(priv, 0x400700, 0x00000002, 0x00000000); addr += init->pitch; - while (nv_rd32(priv, 0x400700) & 0x00000002) {} } } + nv_wr32(priv, 0x400208, 0x00000000); } void -nvc0_graph_mthd(struct nvc0_graph_priv *priv, struct nvc0_graph_mthd *mthds) +nvc0_graph_mthd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p) { - struct nvc0_graph_mthd *mthd; - struct nvc0_graph_init *init; - int i = 0, j; - u32 data; - - while ((mthd = &mthds[i++]) && (init = mthd->init)) { - u32 addr = 0x80000000 | mthd->oclass; - for (data = 0; init->count; init++) { - if (init == mthd->init || data != init->data) { - nv_wr32(priv, 0x40448c, init->data); - data = init->data; - } + const struct nvc0_graph_pack *pack; + const struct nvc0_graph_init *init; + u32 data = 0; - addr = (addr & 0x8000ffff) | (init->addr << 14); - for (j = 0; j < init->count; j++) { - nv_wr32(priv, 0x404488, addr); - addr += init->pitch << 14; - } + pack_for_each_init(init, pack, p) { + u32 ctrl = 0x80000000 | pack->type; + u32 next = init->addr + init->count * init->pitch; + u32 addr = init->addr; + + if ((pack == p && init == p->init) || data != init->data) { + nv_wr32(priv, 0x40448c, init->data); + data = init->data; + } + + while (addr < next) { + nv_wr32(priv, 0x404488, ctrl | (addr << 14)); + addr += init->pitch; } } } @@ -663,17 +789,40 @@ nvc0_graph_ctxctl_debug(struct nvc0_graph_priv *priv) static void nvc0_graph_ctxctl_isr(struct nvc0_graph_priv *priv) { - u32 ustat = nv_rd32(priv, 0x409c18); + u32 stat = nv_rd32(priv, 0x409c18); + + if (stat & 0x00000001) { + u32 code = nv_rd32(priv, 0x409814); + if (code == E_BAD_FWMTHD) { + u32 class = nv_rd32(priv, 0x409808); + u32 addr = nv_rd32(priv, 0x40980c); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00003ffc); + u32 data = nv_rd32(priv, 0x409810); + + nv_error(priv, "FECS MTHD subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + subc, class, mthd, data); - if (ustat & 0x00000001) - nv_error(priv, "CTXCTL ucode error\n"); - if (ustat & 0x00080000) - nv_error(priv, "CTXCTL watchdog timeout\n"); - if (ustat & ~0x00080001) - nv_error(priv, "CTXCTL 0x%08x\n", ustat); + nv_wr32(priv, 0x409c20, 0x00000001); + stat &= ~0x00000001; + } else { + nv_error(priv, "FECS ucode error %d\n", code); + } + } + + if (stat & 0x00080000) { + nv_error(priv, "FECS watchdog timeout\n"); + nvc0_graph_ctxctl_debug(priv); + nv_wr32(priv, 0x409c20, 0x00080000); + stat &= ~0x00080000; + } - nvc0_graph_ctxctl_debug(priv); - nv_wr32(priv, 0x409c20, ustat); + if (stat) { + nv_error(priv, "FECS 0x%08x\n", stat); + nvc0_graph_ctxctl_debug(priv); + nv_wr32(priv, 0x409c20, stat); + } } static void @@ -768,15 +917,20 @@ nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base, nv_wr32(priv, fuc_base + 0x0188, i >> 6); nv_wr32(priv, fuc_base + 0x0184, code->data[i]); } + + /* code must be padded to 0x40 words */ + for (; i & 0x3f; i++) + nv_wr32(priv, fuc_base + 0x0184, 0); } static void nvc0_graph_init_csdata(struct nvc0_graph_priv *priv, - struct nvc0_graph_init *init, + const struct nvc0_graph_pack *pack, u32 falcon, u32 starstar, u32 base) { - u32 addr = init->addr; - u32 next = addr; + const struct nvc0_graph_pack *iter; + const struct nvc0_graph_init *init; + u32 addr = ~0, prev = ~0, xfer = 0; u32 star, temp; nv_wr32(priv, falcon + 0x01c0, 0x02000000 + starstar); @@ -786,22 +940,28 @@ nvc0_graph_init_csdata(struct nvc0_graph_priv *priv, star = temp; nv_wr32(priv, falcon + 0x01c0, 0x01000000 + star); - do { - if (init->addr != next) { - while (addr < next) { - u32 nr = min((int)(next - addr) / 4, 32); - nv_wr32(priv, falcon + 0x01c4, - ((nr - 1) << 26) | (addr - base)); - addr += nr * 4; - star += 4; + pack_for_each_init(init, iter, pack) { + u32 head = init->addr - base; + u32 tail = head + init->count * init->pitch; + while (head < tail) { + if (head != prev + 4 || xfer >= 32) { + if (xfer) { + u32 data = ((--xfer << 26) | addr); + nv_wr32(priv, falcon + 0x01c4, data); + star += 4; + } + addr = head; + xfer = 0; } - addr = next = init->addr; + prev = head; + xfer = xfer + 1; + head = head + init->pitch; } - next += init->count * 4; - } while ((init++)->count); + } + nv_wr32(priv, falcon + 0x01c4, (--xfer << 26) | addr); nv_wr32(priv, falcon + 0x01c0, 0x01000004 + starstar); - nv_wr32(priv, falcon + 0x01c4, star); + nv_wr32(priv, falcon + 0x01c4, star + 4); } int @@ -809,7 +969,6 @@ 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; - struct nvc0_graph_init *init; u32 r000260; int i; @@ -919,10 +1078,6 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv) nv_wr32(priv, 0x409184, oclass->fecs.ucode->code.data[i]); } - for (i = 0; (init = cclass->hub[i]); i++) { - nvc0_graph_init_csdata(priv, init, 0x409000, 0x000, 0x000000); - } - /* load GPC microcode */ nv_wr32(priv, 0x41a1c0, 0x01000000); for (i = 0; i < oclass->gpccs.ucode->data.size / 4; i++) @@ -936,12 +1091,11 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv) } nv_wr32(priv, 0x000260, r000260); - if ((init = cclass->gpc[0])) - nvc0_graph_init_csdata(priv, init, 0x41a000, 0x000, 0x418000); - if ((init = cclass->gpc[2])) - nvc0_graph_init_csdata(priv, init, 0x41a000, 0x004, 0x419800); - if ((init = cclass->gpc[3])) - nvc0_graph_init_csdata(priv, init, 0x41a000, 0x008, 0x41be00); + /* load register lists */ + nvc0_graph_init_csdata(priv, cclass->hub, 0x409000, 0x000, 0x000000); + nvc0_graph_init_csdata(priv, cclass->gpc, 0x41a000, 0x000, 0x418000); + nvc0_graph_init_csdata(priv, cclass->tpc, 0x41a000, 0x004, 0x419800); + nvc0_graph_init_csdata(priv, cclass->ppc, 0x41a000, 0x008, 0x41be00); /* start HUB ucode running, it'll init the GPCs */ nv_wr32(priv, 0x40910c, 0x00000000); @@ -988,8 +1142,7 @@ nvc0_graph_init(struct nouveau_object *object) nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8); nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8); - for (i = 0; oclass->mmio[i]; i++) - nvc0_graph_mmio(priv, oclass->mmio[i]); + nvc0_graph_mmio(priv, oclass->mmio); memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr)); for (i = 0, gpc = -1; i < priv->tpc_total; i++) { @@ -1091,10 +1244,10 @@ nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname, int ret; snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname); - ret = request_firmware(&fw, f, &device->pdev->dev); + ret = request_firmware(&fw, f, nv_device_base(device)); if (ret) { snprintf(f, sizeof(f), "nouveau/%s", fwname); - ret = request_firmware(&fw, f, &device->pdev->dev); + ret = request_firmware(&fw, f, nv_device_base(device)); if (ret) { nv_error(priv, "failed to load %s\n", fwname); return ret; @@ -1133,10 +1286,14 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvc0_graph_oclass *oclass = (void *)bclass; struct nouveau_device *device = nv_device(parent); struct nvc0_graph_priv *priv; + bool use_ext_fw, enable; int ret, i; - ret = nouveau_graph_create(parent, engine, bclass, - (oclass->fecs.ucode != NULL), &priv); + use_ext_fw = nouveau_boolopt(device->cfgopt, "NvGrUseFW", + oclass->fecs.ucode == NULL); + enable = use_ext_fw || oclass->fecs.ucode != NULL; + + ret = nouveau_graph_create(parent, engine, bclass, enable, &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -1146,7 +1303,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->base.units = nvc0_graph_units; - if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { + if (use_ext_fw) { nv_info(priv, "using external firmware\n"); if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) || nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) || @@ -1220,22 +1377,6 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nvc0_graph_init * -nvc0_graph_init_mmio[] = { - nvc0_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvc0_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvc0_graph_init_gpc, - nvc0_graph_init_tpc, - nvc0_graph_init_unk88xx, - nvc0_graph_tpc_0, - NULL -}; - #include "fuc/hubnvc0.fuc.h" struct nvc0_graph_ucode @@ -1267,7 +1408,7 @@ nvc0_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nvc0_grctx_oclass, .sclass = nvc0_graph_sclass, - .mmio = nvc0_graph_init_mmio, + .mmio = nvc0_graph_pack_mmio, .fecs.ucode = &nvc0_graph_fecs_ucode, .gpccs.ucode = &nvc0_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h index b0ab6de270b..ffc289198dd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h @@ -38,6 +38,8 @@ #include <engine/fifo.h> #include <engine/graph.h> +#include "fuc/os.h" + #define GPC_MAX 32 #define TPC_MAX (GPC_MAX * 8) @@ -45,6 +47,7 @@ #define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r)) #define GPC_BCAST(r) (0x418000 + (r)) #define GPC_UNIT(t, r) (0x500000 + (t) * 0x8000 + (r)) +#define PPC_UNIT(t, m, r) (0x503000 + (t) * 0x8000 + (m) * 0x200 + (r)) #define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) struct nvc0_graph_data { @@ -102,8 +105,6 @@ struct nvc0_graph_chan { } data[4]; }; -int nvc0_grctx_generate(struct nvc0_graph_priv *); - int nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *, struct nouveau_oclass *, void *, u32, struct nouveau_object **); @@ -117,6 +118,7 @@ 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 *); +int nve4_graph_fini(struct nouveau_object *, bool); int nve4_graph_init(struct nouveau_object *); extern struct nouveau_oclass nvc0_graph_sclass[]; @@ -130,34 +132,14 @@ struct nvc0_graph_init { u32 data; }; -struct nvc0_graph_mthd { - u16 oclass; - struct nvc0_graph_init *init; +struct nvc0_graph_pack { + const struct nvc0_graph_init *init; + u32 type; }; -struct nvc0_grctx { - struct nvc0_graph_priv *priv; - struct nvc0_graph_data *data; - struct nvc0_graph_mmio *mmio; - int buffer_nr; - u64 buffer[4]; - u64 addr; -}; - -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 */ - struct nvc0_graph_init **hub; - struct nvc0_graph_init **gpc; - /* indirect context data, generated with icmds/mthds */ - struct nvc0_graph_init *icmd; - struct nvc0_graph_mthd *mthd; -}; +#define pack_for_each_init(init, pack, head) \ + for (pack = head; pack && pack->init; pack++) \ + for (init = pack->init; init && init->count; init++) struct nvc0_graph_ucode { struct nvc0_graph_fuc code; @@ -171,7 +153,7 @@ struct nvc0_graph_oclass { struct nouveau_oclass base; struct nouveau_oclass **cclass; struct nouveau_oclass *sclass; - struct nvc0_graph_init **mmio; + const struct nvc0_graph_pack *mmio; struct { struct nvc0_graph_ucode *ucode; } fecs; @@ -180,119 +162,73 @@ struct nvc0_graph_oclass { } gpccs; }; -void nvc0_graph_mmio(struct nvc0_graph_priv *, struct nvc0_graph_init *); -void nvc0_graph_icmd(struct nvc0_graph_priv *, struct nvc0_graph_init *); -void nvc0_graph_mthd(struct nvc0_graph_priv *, struct nvc0_graph_mthd *); +void nvc0_graph_mmio(struct nvc0_graph_priv *, const struct nvc0_graph_pack *); +void nvc0_graph_icmd(struct nvc0_graph_priv *, const struct nvc0_graph_pack *); +void nvc0_graph_mthd(struct nvc0_graph_priv *, const struct nvc0_graph_pack *); int nvc0_graph_init_ctxctl(struct nvc0_graph_priv *); -extern struct nvc0_graph_init nvc0_graph_init_regs[]; -extern struct nvc0_graph_init nvc0_graph_init_unk40xx[]; -extern struct nvc0_graph_init nvc0_graph_init_unk44xx[]; -extern struct nvc0_graph_init nvc0_graph_init_unk78xx[]; -extern struct nvc0_graph_init nvc0_graph_init_unk60xx[]; -extern struct nvc0_graph_init nvc0_graph_init_unk58xx[]; -extern struct nvc0_graph_init nvc0_graph_init_unk80xx[]; -extern struct nvc0_graph_init nvc0_graph_init_gpc[]; -extern struct nvc0_graph_init nvc0_graph_init_unk88xx[]; -extern struct nvc0_graph_init nvc0_graph_tpc_0[]; - -extern struct nvc0_graph_init nvc3_graph_init_unk58xx[]; - -extern struct nvc0_graph_init nvd9_graph_init_unk58xx[]; -extern struct nvc0_graph_init nvd9_graph_init_unk64xx[]; - -extern struct nvc0_graph_init nve4_graph_init_regs[]; -extern struct nvc0_graph_init nve4_graph_init_unk[]; -extern struct nvc0_graph_init nve4_graph_init_unk88xx[]; - -extern struct nvc0_graph_init nvf0_graph_init_unk40xx[]; -extern struct nvc0_graph_init nvf0_graph_init_unk70xx[]; -extern struct nvc0_graph_init nvf0_graph_init_unk5bxx[]; -extern struct nvc0_graph_init nvf0_graph_init_tpc[]; - -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_unkn(struct nvc0_graph_priv *); -void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *); -void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *); -void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *); -void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *); -void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *); -void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *); - -extern struct nouveau_oclass *nvc0_grctx_oclass; -extern struct nvc0_graph_init *nvc0_grctx_init_hub[]; -extern struct nvc0_graph_init nvc0_grctx_init_base[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk40xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk44xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk46xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk47xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk60xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk64xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk78xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_unk80xx[]; -extern struct nvc0_graph_init nvc0_grctx_init_gpc_0[]; -extern struct nvc0_graph_init nvc0_grctx_init_gpc_1[]; -extern struct nvc0_graph_init nvc0_grctx_init_tpc[]; -extern struct nvc0_graph_init nvc0_grctx_init_icmd[]; -extern struct nvc0_graph_init nvd9_grctx_init_icmd[]; // - -extern struct nvc0_graph_mthd nvc0_grctx_init_mthd[]; -extern struct nvc0_graph_init nvc0_grctx_init_902d[]; -extern struct nvc0_graph_init nvc0_grctx_init_9039[]; -extern struct nvc0_graph_init nvc0_grctx_init_90c0[]; -extern struct nvc0_graph_init nvc0_grctx_init_mthd_magic[]; - -void nvc1_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *); -void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *); -extern struct nouveau_oclass *nvc1_grctx_oclass; -extern struct nvc0_graph_init nvc1_grctx_init_9097[]; - -extern struct nouveau_oclass *nvc3_grctx_oclass; - -extern struct nouveau_oclass *nvc8_grctx_oclass; -extern struct nvc0_graph_init nvc8_grctx_init_9197[]; -extern struct nvc0_graph_init nvc8_grctx_init_9297[]; - -extern struct nouveau_oclass *nvd7_grctx_oclass; - -extern struct nouveau_oclass *nvd9_grctx_oclass; -extern struct nvc0_graph_init nvd9_grctx_init_rop[]; -extern struct nvc0_graph_mthd nvd9_grctx_init_mthd[]; - -void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *); -void nve4_grctx_generate_unkn(struct nvc0_graph_priv *); -extern struct nouveau_oclass *nve4_grctx_oclass; -extern struct nvc0_graph_init nve4_grctx_init_unk46xx[]; -extern struct nvc0_graph_init nve4_grctx_init_unk47xx[]; -extern struct nvc0_graph_init nve4_grctx_init_unk58xx[]; -extern struct nvc0_graph_init nve4_grctx_init_unk80xx[]; -extern struct nvc0_graph_init nve4_grctx_init_unk90xx[]; - -extern struct nouveau_oclass *nvf0_grctx_oclass; -extern struct nvc0_graph_init nvf0_grctx_init_unk44xx[]; -extern struct nvc0_graph_init nvf0_grctx_init_unk5bxx[]; -extern struct nvc0_graph_init nvf0_grctx_init_unk60xx[]; - -extern struct nouveau_oclass *nv108_grctx_oclass; - -#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) +/* register init value lists */ + +extern const struct nvc0_graph_init nvc0_graph_init_main_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_fe_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_pri_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_rstr2d_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_pd_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_ds_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_scc_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_prop_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_gpc_unk_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_setup_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_crstr_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_setup_1[]; +extern const struct nvc0_graph_init nvc0_graph_init_zcull_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_gpm_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_gpc_unk_1[]; +extern const struct nvc0_graph_init nvc0_graph_init_gcc_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_tpccs_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_tex_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_pe_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_l1c_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_wwdx_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_tpccs_1[]; +extern const struct nvc0_graph_init nvc0_graph_init_mpc_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_be_0[]; +extern const struct nvc0_graph_init nvc0_graph_init_fe_1[]; +extern const struct nvc0_graph_init nvc0_graph_init_pe_1[]; + +extern const struct nvc0_graph_init nvc4_graph_init_ds_0[]; +extern const struct nvc0_graph_init nvc4_graph_init_tex_0[]; +extern const struct nvc0_graph_init nvc4_graph_init_sm_0[]; + +extern const struct nvc0_graph_init nvc1_graph_init_gpc_unk_0[]; +extern const struct nvc0_graph_init nvc1_graph_init_setup_1[]; + +extern const struct nvc0_graph_init nvd9_graph_init_pd_0[]; +extern const struct nvc0_graph_init nvd9_graph_init_ds_0[]; +extern const struct nvc0_graph_init nvd9_graph_init_prop_0[]; +extern const struct nvc0_graph_init nvd9_graph_init_gpm_0[]; +extern const struct nvc0_graph_init nvd9_graph_init_gpc_unk_1[]; +extern const struct nvc0_graph_init nvd9_graph_init_tex_0[]; +extern const struct nvc0_graph_init nvd9_graph_init_sm_0[]; +extern const struct nvc0_graph_init nvd9_graph_init_fe_1[]; + +extern const struct nvc0_graph_init nvd7_graph_init_pes_0[]; +extern const struct nvc0_graph_init nvd7_graph_init_wwdx_0[]; +extern const struct nvc0_graph_init nvd7_graph_init_cbm_0[]; + +extern const struct nvc0_graph_init nve4_graph_init_main_0[]; +extern const struct nvc0_graph_init nve4_graph_init_tpccs_0[]; +extern const struct nvc0_graph_init nve4_graph_init_pe_0[]; +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_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_sm_0[]; + +extern const struct nvc0_graph_init nv108_graph_init_gpc_unk_0[]; + #endif diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c index bc4a469b86c..30cab0b2eba 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c @@ -23,6 +23,7 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* * Graphics object classes @@ -39,94 +40,82 @@ nvc1_graph_sclass[] = { }; /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -static struct nvc0_graph_init -nvc1_graph_init_gpc[] = { - { 0x4184a0, 1, 0x04, 0x00000000 }, +const struct nvc0_graph_init +nvc1_graph_init_gpc_unk_0[] = { { 0x418604, 1, 0x04, 0x00000000 }, { 0x418680, 1, 0x04, 0x00000000 }, { 0x418714, 1, 0x04, 0x00000000 }, { 0x418384, 1, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc1_graph_init_setup_1[] = { { 0x4188c8, 2, 0x04, 0x00000000 }, { 0x4188d0, 1, 0x04, 0x00010000 }, { 0x4188d4, 1, 0x04, 0x00000001 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, - { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c88, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvc1_graph_init_gpc_unk_1[] = { { 0x418d00, 1, 0x04, 0x00000000 }, { 0x418f08, 1, 0x04, 0x00000000 }, { 0x418e00, 1, 0x04, 0x00000003 }, { 0x418e08, 1, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvc1_graph_init_tpc[] = { - { 0x419d08, 2, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, - { 0x419ab0, 1, 0x04, 0x00000000 }, - { 0x419ac8, 1, 0x04, 0x00000000 }, - { 0x419ab8, 1, 0x04, 0x000000e7 }, - { 0x419abc, 2, 0x04, 0x00000000 }, - { 0x41980c, 2, 0x04, 0x00000000 }, +static const struct nvc0_graph_init +nvc1_graph_init_pe_0[] = { + { 0x41980c, 1, 0x04, 0x00000010 }, + { 0x419810, 1, 0x04, 0x00000000 }, { 0x419814, 1, 0x04, 0x00000004 }, { 0x419844, 1, 0x04, 0x00000000 }, { 0x41984c, 1, 0x04, 0x00005bc5 }, { 0x419850, 4, 0x04, 0x00000000 }, { 0x419880, 1, 0x04, 0x00000002 }, - { 0x419c98, 1, 0x04, 0x00000000 }, - { 0x419ca8, 1, 0x04, 0x80000000 }, - { 0x419cb4, 1, 0x04, 0x00000000 }, - { 0x419cb8, 1, 0x04, 0x00008bf4 }, - { 0x419cbc, 1, 0x04, 0x28137606 }, - { 0x419cc0, 2, 0x04, 0x00000000 }, - { 0x419bd4, 1, 0x04, 0x00800000 }, - { 0x419bdc, 1, 0x04, 0x00000000 }, - { 0x419d2c, 1, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, - { 0x419e00, 1, 0x04, 0x00000000 }, - { 0x419ea0, 1, 0x04, 0x00000000 }, - { 0x419ea4, 1, 0x04, 0x00000100 }, - { 0x419ea8, 1, 0x04, 0x00001100 }, - { 0x419eac, 1, 0x04, 0x11100702 }, - { 0x419eb0, 1, 0x04, 0x00000003 }, - { 0x419eb4, 4, 0x04, 0x00000000 }, - { 0x419ec8, 1, 0x04, 0x0e063818 }, - { 0x419ecc, 1, 0x04, 0x0e060e06 }, - { 0x419ed0, 1, 0x04, 0x00003818 }, - { 0x419ed4, 1, 0x04, 0x011104f1 }, - { 0x419edc, 1, 0x04, 0x00000000 }, - { 0x419f00, 1, 0x04, 0x00000000 }, - { 0x419f2c, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init * -nvc1_graph_init_mmio[] = { - nvc0_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvc3_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvc1_graph_init_gpc, - nvc1_graph_init_tpc, - nvc0_graph_init_unk88xx, - nvc0_graph_tpc_0, - NULL +static const struct nvc0_graph_pack +nvc1_graph_pack_mmio[] = { + { nvc0_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvc0_graph_init_pd_0 }, + { nvc4_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nvc0_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 }, + { nvc0_graph_init_gpm_0 }, + { nvc1_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nvc0_graph_init_tpccs_0 }, + { nvc4_graph_init_tex_0 }, + { nvc1_graph_init_pe_0 }, + { nvc0_graph_init_l1c_0 }, + { nvc0_graph_init_wwdx_0 }, + { nvc0_graph_init_tpccs_1 }, + { nvc0_graph_init_mpc_0 }, + { nvc4_graph_init_sm_0 }, + { nvc0_graph_init_be_0 }, + { nvc0_graph_init_fe_1 }, + {} }; +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + struct nouveau_oclass * nvc1_graph_oclass = &(struct nvc0_graph_oclass) { .base.handle = NV_ENGINE(GR, 0xc1), @@ -138,7 +127,7 @@ nvc1_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nvc1_grctx_oclass, .sclass = nvc1_graph_sclass, - .mmio = nvc1_graph_init_mmio, + .mmio = nvc1_graph_pack_mmio, .fecs.ucode = &nvc0_graph_fecs_ucode, .gpccs.ucode = &nvc0_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c index d44b3b3ee80..e82e70c5313 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c @@ -23,13 +23,14 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -struct nvc0_graph_init -nvc3_graph_init_unk58xx[] = { +const struct nvc0_graph_init +nvc4_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, { 0x405900, 1, 0x04, 0x00002834 }, @@ -37,29 +38,27 @@ nvc3_graph_init_unk58xx[] = { {} }; -static struct nvc0_graph_init -nvc3_graph_init_tpc[] = { - { 0x419d08, 2, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, +const struct nvc0_graph_init +nvc4_graph_init_tex_0[] = { { 0x419ab0, 1, 0x04, 0x00000000 }, { 0x419ac8, 1, 0x04, 0x00000000 }, { 0x419ab8, 1, 0x04, 0x000000e7 }, { 0x419abc, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvc4_graph_init_pe_0[] = { { 0x41980c, 3, 0x04, 0x00000000 }, { 0x419844, 1, 0x04, 0x00000000 }, { 0x41984c, 1, 0x04, 0x00005bc5 }, { 0x419850, 4, 0x04, 0x00000000 }, { 0x419880, 1, 0x04, 0x00000002 }, - { 0x419c98, 1, 0x04, 0x00000000 }, - { 0x419ca8, 1, 0x04, 0x80000000 }, - { 0x419cb4, 1, 0x04, 0x00000000 }, - { 0x419cb8, 1, 0x04, 0x00008bf4 }, - { 0x419cbc, 1, 0x04, 0x28137606 }, - { 0x419cc0, 2, 0x04, 0x00000000 }, - { 0x419bd4, 1, 0x04, 0x00800000 }, - { 0x419bdc, 1, 0x04, 0x00000000 }, - { 0x419d2c, 1, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvc4_graph_init_sm_0[] = { { 0x419e00, 1, 0x04, 0x00000000 }, { 0x419ea0, 1, 0x04, 0x00000000 }, { 0x419ea4, 1, 0x04, 0x00000100 }, @@ -77,24 +76,43 @@ nvc3_graph_init_tpc[] = { {} }; -static struct nvc0_graph_init * -nvc3_graph_init_mmio[] = { - nvc0_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvc3_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvc0_graph_init_gpc, - nvc3_graph_init_tpc, - nvc0_graph_init_unk88xx, - nvc0_graph_tpc_0, - NULL +static const struct nvc0_graph_pack +nvc4_graph_pack_mmio[] = { + { nvc0_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvc0_graph_init_pd_0 }, + { nvc4_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nvc0_graph_init_prop_0 }, + { nvc0_graph_init_gpc_unk_0 }, + { nvc0_graph_init_setup_0 }, + { nvc0_graph_init_crstr_0 }, + { nvc0_graph_init_setup_1 }, + { nvc0_graph_init_zcull_0 }, + { nvc0_graph_init_gpm_0 }, + { nvc0_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nvc0_graph_init_tpccs_0 }, + { nvc4_graph_init_tex_0 }, + { nvc4_graph_init_pe_0 }, + { nvc0_graph_init_l1c_0 }, + { nvc0_graph_init_wwdx_0 }, + { nvc0_graph_init_tpccs_1 }, + { nvc0_graph_init_mpc_0 }, + { nvc4_graph_init_sm_0 }, + { nvc0_graph_init_be_0 }, + { nvc0_graph_init_fe_1 }, + {} }; +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + struct nouveau_oclass * -nvc3_graph_oclass = &(struct nvc0_graph_oclass) { +nvc4_graph_oclass = &(struct nvc0_graph_oclass) { .base.handle = NV_ENGINE(GR, 0xc3), .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nvc0_graph_ctor, @@ -102,9 +120,9 @@ nvc3_graph_oclass = &(struct nvc0_graph_oclass) { .init = nvc0_graph_init, .fini = _nouveau_graph_fini, }, - .cclass = &nvc3_grctx_oclass, + .cclass = &nvc4_grctx_oclass, .sclass = nvc0_graph_sclass, - .mmio = nvc3_graph_init_mmio, + .mmio = nvc4_graph_pack_mmio, .fecs.ucode = &nvc0_graph_fecs_ucode, .gpccs.ucode = &nvc0_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c index 02845e56731..a6bf783e125 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c @@ -23,6 +23,7 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* * Graphics object classes @@ -40,58 +41,11 @@ nvc8_graph_sclass[] = { }; /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -static struct nvc0_graph_init -nvc8_graph_init_gpc[] = { - { 0x4184a0, 1, 0x04, 0x00000000 }, - { 0x418604, 1, 0x04, 0x00000000 }, - { 0x418680, 1, 0x04, 0x00000000 }, - { 0x418714, 1, 0x04, 0x80000000 }, - { 0x418384, 1, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, - { 0x4188c8, 2, 0x04, 0x00000000 }, - { 0x4188d0, 1, 0x04, 0x00010000 }, - { 0x4188d4, 1, 0x04, 0x00000001 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, - { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c88, 1, 0x04, 0x00000000 }, - { 0x418d00, 1, 0x04, 0x00000000 }, - { 0x418f08, 1, 0x04, 0x00000000 }, - { 0x418e00, 1, 0x04, 0x00000050 }, - { 0x418e08, 1, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, - {} -}; - -static struct nvc0_graph_init -nvc8_graph_init_tpc[] = { - { 0x419d08, 2, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, - { 0x419ab0, 1, 0x04, 0x00000000 }, - { 0x419ab8, 1, 0x04, 0x000000e7 }, - { 0x419abc, 2, 0x04, 0x00000000 }, - { 0x41980c, 3, 0x04, 0x00000000 }, - { 0x419844, 1, 0x04, 0x00000000 }, - { 0x41984c, 1, 0x04, 0x00005bc5 }, - { 0x419850, 4, 0x04, 0x00000000 }, - { 0x419c98, 1, 0x04, 0x00000000 }, - { 0x419ca8, 1, 0x04, 0x80000000 }, - { 0x419cb4, 1, 0x04, 0x00000000 }, - { 0x419cb8, 1, 0x04, 0x00008bf4 }, - { 0x419cbc, 1, 0x04, 0x28137606 }, - { 0x419cc0, 2, 0x04, 0x00000000 }, - { 0x419bd4, 1, 0x04, 0x00800000 }, - { 0x419bdc, 1, 0x04, 0x00000000 }, - { 0x419d2c, 1, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, +static const struct nvc0_graph_init +nvc8_graph_init_sm_0[] = { { 0x419e00, 1, 0x04, 0x00000000 }, { 0x419ea0, 1, 0x04, 0x00000000 }, { 0x419ea4, 1, 0x04, 0x00000100 }, @@ -108,22 +62,42 @@ nvc8_graph_init_tpc[] = { {} }; -static struct nvc0_graph_init * -nvc8_graph_init_mmio[] = { - nvc0_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvc0_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvc8_graph_init_gpc, - nvc8_graph_init_tpc, - nvc0_graph_init_unk88xx, - nvc0_graph_tpc_0, - NULL +static const struct nvc0_graph_pack +nvc8_graph_pack_mmio[] = { + { nvc0_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvc0_graph_init_pd_0 }, + { nvc0_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nvc0_graph_init_prop_0 }, + { nvc0_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 }, + { nvc0_graph_init_gpm_0 }, + { nvc0_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nvc0_graph_init_tpccs_0 }, + { nvc0_graph_init_tex_0 }, + { nvc0_graph_init_pe_0 }, + { nvc0_graph_init_l1c_0 }, + { nvc0_graph_init_wwdx_0 }, + { nvc0_graph_init_tpccs_1 }, + { nvc0_graph_init_mpc_0 }, + { nvc8_graph_init_sm_0 }, + { nvc0_graph_init_be_0 }, + { nvc0_graph_init_fe_1 }, + { nvc0_graph_init_pe_1 }, + {} }; +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + struct nouveau_oclass * nvc8_graph_oclass = &(struct nvc0_graph_oclass) { .base.handle = NV_ENGINE(GR, 0xc8), @@ -135,7 +109,7 @@ nvc8_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nvc8_grctx_oclass, .sclass = nvc8_graph_sclass, - .mmio = nvc8_graph_init_mmio, + .mmio = nvc8_graph_pack_mmio, .fecs.ucode = &nvc0_graph_fecs_ucode, .gpccs.ucode = &nvc0_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c index 5052d7ab4d7..2a6a94e2a04 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c @@ -23,6 +23,77 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" + +/******************************************************************************* + * PGRAPH register lists + ******************************************************************************/ + +static const struct nvc0_graph_init +nvd7_graph_init_pe_0[] = { + { 0x41980c, 1, 0x04, 0x00000010 }, + { 0x419844, 1, 0x04, 0x00000000 }, + { 0x41984c, 1, 0x04, 0x00005bc8 }, + { 0x419850, 3, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd7_graph_init_pes_0[] = { + { 0x41be04, 1, 0x04, 0x00000000 }, + { 0x41be08, 1, 0x04, 0x00000004 }, + { 0x41be0c, 1, 0x04, 0x00000000 }, + { 0x41be10, 1, 0x04, 0x003b8bc7 }, + { 0x41be14, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd7_graph_init_wwdx_0[] = { + { 0x41bfd4, 1, 0x04, 0x00800000 }, + { 0x41bfdc, 1, 0x04, 0x00000000 }, + { 0x41bff8, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd7_graph_init_cbm_0[] = { + { 0x41becc, 1, 0x04, 0x00000000 }, + { 0x41bee8, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_pack +nvd7_graph_pack_mmio[] = { + { nvc0_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvd9_graph_init_pd_0 }, + { nvd9_graph_init_ds_0 }, + { nvc0_graph_init_scc_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 }, + { nvd9_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nvc0_graph_init_tpccs_0 }, + { nvd9_graph_init_tex_0 }, + { nvd7_graph_init_pe_0 }, + { nvc0_graph_init_l1c_0 }, + { nvc0_graph_init_mpc_0 }, + { nvd9_graph_init_sm_0 }, + { nvd7_graph_init_pes_0 }, + { nvd7_graph_init_wwdx_0 }, + { nvd7_graph_init_cbm_0 }, + { nvc0_graph_init_be_0 }, + { nvd9_graph_init_fe_1 }, + {} +}; /******************************************************************************* * PGRAPH engine/subdev functions @@ -48,108 +119,6 @@ nvd7_graph_gpccs_ucode = { .data.size = sizeof(nvd7_grgpc_data), }; -static struct nvc0_graph_init -nvd7_graph_init_gpc[] = { - { 0x418408, 1, 0x04, 0x00000000 }, - { 0x4184a0, 1, 0x04, 0x00000000 }, - { 0x4184a4, 2, 0x04, 0x00000000 }, - { 0x418604, 1, 0x04, 0x00000000 }, - { 0x418680, 1, 0x04, 0x00000000 }, - { 0x418714, 1, 0x04, 0x00000000 }, - { 0x418384, 1, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, - { 0x4188c8, 2, 0x04, 0x00000000 }, - { 0x4188d0, 1, 0x04, 0x00010000 }, - { 0x4188d4, 1, 0x04, 0x00000001 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, - { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c64, 1, 0x04, 0x00000000 }, - { 0x418c68, 1, 0x04, 0x00000000 }, - { 0x418c88, 1, 0x04, 0x00000000 }, - { 0x418cb4, 2, 0x04, 0x00000000 }, - { 0x418d00, 1, 0x04, 0x00000000 }, - { 0x418d28, 1, 0x04, 0x00000000 }, - { 0x418f00, 1, 0x04, 0x00000000 }, - { 0x418f08, 1, 0x04, 0x00000000 }, - { 0x418f20, 2, 0x04, 0x00000000 }, - { 0x418e00, 1, 0x04, 0x00000003 }, - { 0x418e08, 1, 0x04, 0x00000000 }, - { 0x418e1c, 1, 0x04, 0x00000000 }, - { 0x418e20, 1, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, - {} -}; - -static struct nvc0_graph_init -nvd7_graph_init_tpc[] = { - { 0x419d08, 2, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, - { 0x419ab0, 1, 0x04, 0x00000000 }, - { 0x419ac8, 1, 0x04, 0x00000000 }, - { 0x419ab8, 1, 0x04, 0x000000e7 }, - { 0x419abc, 2, 0x04, 0x00000000 }, - { 0x419ab4, 1, 0x04, 0x00000000 }, - { 0x41980c, 1, 0x04, 0x00000010 }, - { 0x419844, 1, 0x04, 0x00000000 }, - { 0x41984c, 1, 0x04, 0x00005bc8 }, - { 0x419850, 2, 0x04, 0x00000000 }, - { 0x419c98, 1, 0x04, 0x00000000 }, - { 0x419ca8, 1, 0x04, 0x80000000 }, - { 0x419cb4, 1, 0x04, 0x00000000 }, - { 0x419cb8, 1, 0x04, 0x00008bf4 }, - { 0x419cbc, 1, 0x04, 0x28137606 }, - { 0x419cc0, 2, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, - { 0x419e00, 1, 0x04, 0x00000000 }, - { 0x419ea0, 1, 0x04, 0x00000000 }, - { 0x419ea4, 1, 0x04, 0x00000100 }, - { 0x419ea8, 1, 0x04, 0x02001100 }, - { 0x419eac, 1, 0x04, 0x11100702 }, - { 0x419eb0, 1, 0x04, 0x00000003 }, - { 0x419eb4, 4, 0x04, 0x00000000 }, - { 0x419ec8, 1, 0x04, 0x0e063818 }, - { 0x419ecc, 1, 0x04, 0x0e060e06 }, - { 0x419ed0, 1, 0x04, 0x00003818 }, - { 0x419ed4, 1, 0x04, 0x011104f1 }, - { 0x419edc, 1, 0x04, 0x00000000 }, - { 0x419f00, 1, 0x04, 0x00000000 }, - { 0x419f2c, 1, 0x04, 0x00000000 }, - {} -}; - -static struct nvc0_graph_init -nvd7_graph_init_tpc_0[] = { - { 0x40402c, 1, 0x04, 0x00000000 }, - { 0x4040f0, 1, 0x04, 0x00000000 }, - { 0x404174, 1, 0x04, 0x00000000 }, - { 0x503018, 1, 0x04, 0x00000001 }, - {} -}; - -static struct nvc0_graph_init * -nvd7_graph_init_mmio[] = { - nvc0_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvd9_graph_init_unk64xx, - nvd9_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvd7_graph_init_gpc, - nvd7_graph_init_tpc, - nve4_graph_init_unk, - nvc0_graph_init_unk88xx, - nvd7_graph_init_tpc_0, - NULL -}; - struct nouveau_oclass * nvd7_graph_oclass = &(struct nvc0_graph_oclass) { .base.handle = NV_ENGINE(GR, 0xd7), @@ -161,7 +130,7 @@ nvd7_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nvd7_grctx_oclass, .sclass = nvc8_graph_sclass, - .mmio = nvd7_graph_init_mmio, + .mmio = nvd7_graph_pack_mmio, .fecs.ucode = &nvd7_graph_fecs_ucode, .gpccs.ucode = &nvd7_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c index 652098e0df3..00fdf202fb9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c @@ -23,76 +23,70 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -struct nvc0_graph_init -nvd9_graph_init_unk64xx[] = { +const struct nvc0_graph_init +nvd9_graph_init_pd_0[] = { + { 0x406024, 1, 0x04, 0x00000000 }, { 0x4064f0, 3, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvd9_graph_init_unk58xx[] = { +const struct nvc0_graph_init +nvd9_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, { 0x405900, 1, 0x04, 0x00002834 }, { 0x405908, 1, 0x04, 0x00000000 }, - { 0x405928, 1, 0x04, 0x00000000 }, - { 0x40592c, 1, 0x04, 0x00000000 }, + { 0x405928, 2, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvd9_graph_init_gpc[] = { +const struct nvc0_graph_init +nvd9_graph_init_prop_0[] = { { 0x418408, 1, 0x04, 0x00000000 }, - { 0x4184a0, 1, 0x04, 0x00000000 }, - { 0x4184a4, 2, 0x04, 0x00000000 }, - { 0x418604, 1, 0x04, 0x00000000 }, - { 0x418680, 1, 0x04, 0x00000000 }, - { 0x418714, 1, 0x04, 0x00000000 }, - { 0x418384, 1, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, - { 0x4188c8, 2, 0x04, 0x00000000 }, - { 0x4188d0, 1, 0x04, 0x00010000 }, - { 0x4188d4, 1, 0x04, 0x00000001 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, + { 0x4184a0, 3, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd9_graph_init_gpm_0[] = { { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c64, 1, 0x04, 0x00000000 }, - { 0x418c68, 1, 0x04, 0x00000000 }, + { 0x418c64, 2, 0x04, 0x00000000 }, { 0x418c88, 1, 0x04, 0x00000000 }, { 0x418cb4, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd9_graph_init_gpc_unk_1[] = { { 0x418d00, 1, 0x04, 0x00000000 }, - { 0x418d28, 1, 0x04, 0x00000000 }, - { 0x418d2c, 1, 0x04, 0x00000000 }, + { 0x418d28, 2, 0x04, 0x00000000 }, { 0x418f00, 1, 0x04, 0x00000000 }, { 0x418f08, 1, 0x04, 0x00000000 }, { 0x418f20, 2, 0x04, 0x00000000 }, { 0x418e00, 1, 0x04, 0x00000003 }, { 0x418e08, 1, 0x04, 0x00000000 }, - { 0x418e1c, 1, 0x04, 0x00000000 }, - { 0x418e20, 1, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, + { 0x418e1c, 2, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvd9_graph_init_tpc[] = { - { 0x419d08, 2, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, +const struct nvc0_graph_init +nvd9_graph_init_tex_0[] = { { 0x419ab0, 1, 0x04, 0x00000000 }, { 0x419ac8, 1, 0x04, 0x00000000 }, { 0x419ab8, 1, 0x04, 0x000000e7 }, { 0x419abc, 2, 0x04, 0x00000000 }, { 0x419ab4, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_graph_init_pe_0[] = { { 0x41980c, 1, 0x04, 0x00000010 }, { 0x419810, 1, 0x04, 0x00000000 }, { 0x419814, 1, 0x04, 0x00000004 }, @@ -100,20 +94,26 @@ nvd9_graph_init_tpc[] = { { 0x41984c, 1, 0x04, 0x0000a918 }, { 0x419850, 4, 0x04, 0x00000000 }, { 0x419880, 1, 0x04, 0x00000002 }, - { 0x419c98, 1, 0x04, 0x00000000 }, - { 0x419ca8, 1, 0x04, 0x80000000 }, - { 0x419cb4, 1, 0x04, 0x00000000 }, - { 0x419cb8, 1, 0x04, 0x00008bf4 }, - { 0x419cbc, 1, 0x04, 0x28137606 }, - { 0x419cc0, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_graph_init_wwdx_0[] = { { 0x419bd4, 1, 0x04, 0x00800000 }, { 0x419bdc, 1, 0x04, 0x00000000 }, - { 0x419bf8, 1, 0x04, 0x00000000 }, - { 0x419bfc, 1, 0x04, 0x00000000 }, + { 0x419bf8, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvd9_graph_init_tpccs_1[] = { { 0x419d2c, 1, 0x04, 0x00000000 }, - { 0x419d48, 1, 0x04, 0x00000000 }, - { 0x419d4c, 1, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, + { 0x419d48, 2, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvd9_graph_init_sm_0[] = { { 0x419e00, 1, 0x04, 0x00000000 }, { 0x419ea0, 1, 0x04, 0x00000000 }, { 0x419ea4, 1, 0x04, 0x00000100 }, @@ -131,23 +131,49 @@ nvd9_graph_init_tpc[] = { {} }; -static struct nvc0_graph_init * -nvd9_graph_init_mmio[] = { - nvc0_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvd9_graph_init_unk64xx, - nvd9_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvd9_graph_init_gpc, - nvd9_graph_init_tpc, - nvc0_graph_init_unk88xx, - nvc0_graph_tpc_0, - NULL +const struct nvc0_graph_init +nvd9_graph_init_fe_1[] = { + { 0x40402c, 1, 0x04, 0x00000000 }, + { 0x4040f0, 1, 0x04, 0x00000000 }, + { 0x404174, 1, 0x04, 0x00000000 }, + {} }; +static const struct nvc0_graph_pack +nvd9_graph_pack_mmio[] = { + { nvc0_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvd9_graph_init_pd_0 }, + { nvd9_graph_init_ds_0 }, + { nvc0_graph_init_scc_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 }, + { nvd9_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nvc0_graph_init_tpccs_0 }, + { nvd9_graph_init_tex_0 }, + { nvd9_graph_init_pe_0 }, + { nvc0_graph_init_l1c_0 }, + { nvd9_graph_init_wwdx_0 }, + { nvd9_graph_init_tpccs_1 }, + { nvc0_graph_init_mpc_0 }, + { nvd9_graph_init_sm_0 }, + { nvc0_graph_init_be_0 }, + { nvd9_graph_init_fe_1 }, + {} +}; + +/******************************************************************************* + * PGRAPH engine/subdev functions + ******************************************************************************/ + struct nouveau_oclass * nvd9_graph_oclass = &(struct nvc0_graph_oclass) { .base.handle = NV_ENGINE(GR, 0xd9), @@ -159,7 +185,7 @@ nvd9_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nvd9_grctx_oclass, .sclass = nvc8_graph_sclass, - .mmio = nvd9_graph_init_mmio, + .mmio = nvd9_graph_pack_mmio, .fecs.ucode = &nvc0_graph_fecs_ucode, .gpccs.ucode = &nvc0_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c index 05ec09c8851..51e0c075ad3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c @@ -23,6 +23,7 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* * Graphics object classes @@ -38,11 +39,11 @@ nve4_graph_sclass[] = { }; /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -struct nvc0_graph_init -nve4_graph_init_regs[] = { +const struct nvc0_graph_init +nve4_graph_init_main_0[] = { { 0x400080, 1, 0x04, 0x003083c2 }, { 0x400088, 1, 0x04, 0x0001ffe7 }, { 0x40008c, 1, 0x04, 0x00000000 }, @@ -57,81 +58,59 @@ nve4_graph_init_regs[] = { {} }; -static struct nvc0_graph_init -nve4_graph_init_unk58xx[] = { +static const struct nvc0_graph_init +nve4_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, { 0x405900, 1, 0x04, 0x0000ff34 }, { 0x405908, 1, 0x04, 0x00000000 }, - { 0x405928, 1, 0x04, 0x00000000 }, - { 0x40592c, 1, 0x04, 0x00000000 }, + { 0x405928, 2, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nve4_graph_init_unk70xx[] = { +static const struct nvc0_graph_init +nve4_graph_init_sked_0[] = { { 0x407010, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nve4_graph_init_unk5bxx[] = { +static const struct nvc0_graph_init +nve4_graph_init_cwd_0[] = { { 0x405b50, 1, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nve4_graph_init_gpc[] = { - { 0x418408, 1, 0x04, 0x00000000 }, - { 0x4184a0, 1, 0x04, 0x00000000 }, - { 0x4184a4, 2, 0x04, 0x00000000 }, - { 0x418604, 1, 0x04, 0x00000000 }, - { 0x418680, 1, 0x04, 0x00000000 }, - { 0x418714, 1, 0x04, 0x00000000 }, - { 0x418384, 1, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, - { 0x4188c8, 2, 0x04, 0x00000000 }, - { 0x4188d0, 1, 0x04, 0x00010000 }, - { 0x4188d4, 1, 0x04, 0x00000001 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, - { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c64, 1, 0x04, 0x00000000 }, - { 0x418c68, 1, 0x04, 0x00000000 }, - { 0x418c88, 1, 0x04, 0x00000000 }, - { 0x418cb4, 2, 0x04, 0x00000000 }, +static const struct nvc0_graph_init +nve4_graph_init_gpc_unk_1[] = { { 0x418d00, 1, 0x04, 0x00000000 }, - { 0x418d28, 1, 0x04, 0x00000000 }, - { 0x418d2c, 1, 0x04, 0x00000000 }, + { 0x418d28, 2, 0x04, 0x00000000 }, { 0x418f00, 1, 0x04, 0x00000000 }, { 0x418f08, 1, 0x04, 0x00000000 }, { 0x418f20, 2, 0x04, 0x00000000 }, { 0x418e00, 1, 0x04, 0x00000060 }, { 0x418e08, 1, 0x04, 0x00000000 }, - { 0x418e1c, 1, 0x04, 0x00000000 }, - { 0x418e20, 1, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, + { 0x418e1c, 2, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nve4_graph_init_tpc[] = { +const struct nvc0_graph_init +nve4_graph_init_tpccs_0[] = { { 0x419d0c, 1, 0x04, 0x00000000 }, { 0x419d10, 1, 0x04, 0x00000014 }, - { 0x419ab0, 1, 0x04, 0x00000000 }, - { 0x419ac8, 1, 0x04, 0x00000000 }, - { 0x419ab8, 1, 0x04, 0x000000e7 }, - { 0x419abc, 2, 0x04, 0x00000000 }, - { 0x419ab4, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nve4_graph_init_pe_0[] = { { 0x41980c, 1, 0x04, 0x00000010 }, { 0x419844, 1, 0x04, 0x00000000 }, { 0x419850, 1, 0x04, 0x00000004 }, { 0x419854, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nve4_graph_init_l1c_0[] = { { 0x419c98, 1, 0x04, 0x00000000 }, { 0x419ca8, 1, 0x04, 0x00000000 }, { 0x419cb0, 1, 0x04, 0x01000000 }, @@ -141,39 +120,25 @@ nve4_graph_init_tpc[] = { { 0x419cbc, 1, 0x04, 0x28137646 }, { 0x419cc0, 2, 0x04, 0x00000000 }, { 0x419c80, 1, 0x04, 0x00020232 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nve4_graph_init_sm_0[] = { { 0x419e00, 1, 0x04, 0x00000000 }, { 0x419ea0, 1, 0x04, 0x00000000 }, { 0x419ee4, 1, 0x04, 0x00000000 }, { 0x419ea4, 1, 0x04, 0x00000100 }, { 0x419ea8, 1, 0x04, 0x00000000 }, - { 0x419eb4, 1, 0x04, 0x00000000 }, - { 0x419eb8, 3, 0x04, 0x00000000 }, + { 0x419eb4, 4, 0x04, 0x00000000 }, { 0x419edc, 1, 0x04, 0x00000000 }, { 0x419f00, 1, 0x04, 0x00000000 }, { 0x419f74, 1, 0x04, 0x00000555 }, {} }; -struct nvc0_graph_init -nve4_graph_init_unk[] = { - { 0x41be04, 1, 0x04, 0x00000000 }, - { 0x41be08, 1, 0x04, 0x00000004 }, - { 0x41be0c, 1, 0x04, 0x00000000 }, - { 0x41be10, 1, 0x04, 0x003b8bc7 }, - { 0x41be14, 2, 0x04, 0x00000000 }, - { 0x41bfd4, 1, 0x04, 0x00800000 }, - { 0x41bfdc, 1, 0x04, 0x00000000 }, - { 0x41bff8, 1, 0x04, 0x00000000 }, - { 0x41bffc, 1, 0x04, 0x00000000 }, - { 0x41becc, 1, 0x04, 0x00000000 }, - { 0x41bee8, 1, 0x04, 0x00000000 }, - { 0x41beec, 1, 0x04, 0x00000000 }, - {} -}; - -struct nvc0_graph_init -nve4_graph_init_unk88xx[] = { +const struct nvc0_graph_init +nve4_graph_init_be_0[] = { { 0x40880c, 1, 0x04, 0x00000000 }, { 0x408850, 1, 0x04, 0x00000004 }, { 0x408910, 9, 0x04, 0x00000000 }, @@ -186,6 +151,67 @@ nve4_graph_init_unk88xx[] = { {} }; +const struct nvc0_graph_pack +nve4_graph_pack_mmio[] = { + { nve4_graph_init_main_0 }, + { nvc0_graph_init_fe_0 }, + { nvc0_graph_init_pri_0 }, + { nvc0_graph_init_rstr2d_0 }, + { nvd9_graph_init_pd_0 }, + { nve4_graph_init_ds_0 }, + { nvc0_graph_init_scc_0 }, + { nve4_graph_init_sked_0 }, + { nve4_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 }, + { nve4_graph_init_gpc_unk_1 }, + { nvc0_graph_init_gcc_0 }, + { nve4_graph_init_tpccs_0 }, + { nvd9_graph_init_tex_0 }, + { nve4_graph_init_pe_0 }, + { nve4_graph_init_l1c_0 }, + { nvc0_graph_init_mpc_0 }, + { nve4_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 + ******************************************************************************/ + +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) { @@ -210,8 +236,7 @@ nve4_graph_init(struct nouveau_object *object) nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8); nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8); - for (i = 0; oclass->mmio[i]; i++) - nvc0_graph_mmio(priv, oclass->mmio[i]); + nvc0_graph_mmio(priv, oclass->mmio); nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001); @@ -298,25 +323,6 @@ nve4_graph_init(struct nouveau_object *object) return nvc0_graph_init_ctxctl(priv); } -static struct nvc0_graph_init * -nve4_graph_init_mmio[] = { - nve4_graph_init_regs, - nvc0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvd9_graph_init_unk64xx, - nve4_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nve4_graph_init_unk70xx, - nve4_graph_init_unk5bxx, - nve4_graph_init_gpc, - nve4_graph_init_tpc, - nve4_graph_init_unk, - nve4_graph_init_unk88xx, - NULL -}; - #include "fuc/hubnve0.fuc.h" static struct nvc0_graph_ucode @@ -344,11 +350,11 @@ nve4_graph_oclass = &(struct nvc0_graph_oclass) { .ctor = nvc0_graph_ctor, .dtor = nvc0_graph_dtor, .init = nve4_graph_init, - .fini = _nouveau_graph_fini, + .fini = nve4_graph_fini, }, .cclass = &nve4_grctx_oclass, .sclass = nve4_graph_sclass, - .mmio = nve4_graph_init_mmio, + .mmio = nve4_graph_pack_mmio, .fecs.ucode = &nve4_graph_fecs_ucode, .gpccs.ucode = &nve4_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c index b1acb9939d9..c96762122b9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c @@ -23,6 +23,7 @@ */ #include "nvc0.h" +#include "ctxnvc0.h" /******************************************************************************* * Graphics object classes @@ -38,86 +39,57 @@ nvf0_graph_sclass[] = { }; /******************************************************************************* - * PGRAPH engine/subdev functions + * PGRAPH register lists ******************************************************************************/ -struct nvc0_graph_init -nvf0_graph_init_unk40xx[] = { +const struct nvc0_graph_init +nvf0_graph_init_fe_0[] = { { 0x40415c, 1, 0x04, 0x00000000 }, { 0x404170, 1, 0x04, 0x00000000 }, { 0x4041b4, 1, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvf0_graph_init_unk58xx[] = { +static const struct nvc0_graph_init +nvf0_graph_init_ds_0[] = { { 0x405844, 1, 0x04, 0x00ffffff }, { 0x405850, 1, 0x04, 0x00000000 }, { 0x405900, 1, 0x04, 0x0000ff00 }, { 0x405908, 1, 0x04, 0x00000000 }, - { 0x405928, 1, 0x04, 0x00000000 }, - { 0x40592c, 1, 0x04, 0x00000000 }, + { 0x405928, 2, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvf0_graph_init_unk70xx[] = { +const struct nvc0_graph_init +nvf0_graph_init_sked_0[] = { { 0x407010, 1, 0x04, 0x00000000 }, { 0x407040, 1, 0x04, 0x80440424 }, { 0x407048, 1, 0x04, 0x0000000a }, {} }; -struct nvc0_graph_init -nvf0_graph_init_unk5bxx[] = { +const struct nvc0_graph_init +nvf0_graph_init_cwd_0[] = { { 0x405b44, 1, 0x04, 0x00000000 }, { 0x405b50, 1, 0x04, 0x00000000 }, {} }; -static struct nvc0_graph_init -nvf0_graph_init_gpc[] = { - { 0x418408, 1, 0x04, 0x00000000 }, - { 0x4184a0, 1, 0x04, 0x00000000 }, - { 0x4184a4, 2, 0x04, 0x00000000 }, - { 0x418604, 1, 0x04, 0x00000000 }, - { 0x418680, 1, 0x04, 0x00000000 }, - { 0x418714, 1, 0x04, 0x00000000 }, - { 0x418384, 1, 0x04, 0x00000000 }, - { 0x418814, 3, 0x04, 0x00000000 }, - { 0x418b04, 1, 0x04, 0x00000000 }, - { 0x4188c8, 2, 0x04, 0x00000000 }, - { 0x4188d0, 1, 0x04, 0x00010000 }, - { 0x4188d4, 1, 0x04, 0x00000001 }, - { 0x418910, 1, 0x04, 0x00010001 }, - { 0x418914, 1, 0x04, 0x00000301 }, - { 0x418918, 1, 0x04, 0x00800000 }, - { 0x418980, 1, 0x04, 0x77777770 }, - { 0x418984, 3, 0x04, 0x77777777 }, - { 0x418c04, 1, 0x04, 0x00000000 }, - { 0x418c64, 1, 0x04, 0x00000000 }, - { 0x418c68, 1, 0x04, 0x00000000 }, - { 0x418c88, 1, 0x04, 0x00000000 }, - { 0x418cb4, 2, 0x04, 0x00000000 }, +const struct nvc0_graph_init +nvf0_graph_init_gpc_unk_1[] = { { 0x418d00, 1, 0x04, 0x00000000 }, - { 0x418d28, 1, 0x04, 0x00000000 }, - { 0x418d2c, 1, 0x04, 0x00000000 }, + { 0x418d28, 2, 0x04, 0x00000000 }, { 0x418f00, 1, 0x04, 0x00000400 }, { 0x418f08, 1, 0x04, 0x00000000 }, - { 0x418f20, 1, 0x04, 0x00000000 }, - { 0x418f24, 1, 0x04, 0x00000000 }, + { 0x418f20, 2, 0x04, 0x00000000 }, { 0x418e00, 1, 0x04, 0x00000000 }, { 0x418e08, 1, 0x04, 0x00000000 }, { 0x418e1c, 2, 0x04, 0x00000000 }, - { 0x41900c, 1, 0x04, 0x00000000 }, - { 0x419018, 1, 0x04, 0x00000000 }, {} }; -struct nvc0_graph_init -nvf0_graph_init_tpc[] = { - { 0x419d0c, 1, 0x04, 0x00000000 }, - { 0x419d10, 1, 0x04, 0x00000014 }, +static const struct nvc0_graph_init +nvf0_graph_init_tex_0[] = { { 0x419ab0, 1, 0x04, 0x00000000 }, { 0x419ac8, 1, 0x04, 0x00000000 }, { 0x419ab8, 1, 0x04, 0x000000e7 }, @@ -125,10 +97,11 @@ nvf0_graph_init_tpc[] = { { 0x419abc, 2, 0x04, 0x00000000 }, { 0x419ab4, 1, 0x04, 0x00000000 }, { 0x419aa8, 2, 0x04, 0x00000000 }, - { 0x41980c, 1, 0x04, 0x00000010 }, - { 0x419844, 1, 0x04, 0x00000000 }, - { 0x419850, 1, 0x04, 0x00000004 }, - { 0x419854, 2, 0x04, 0x00000000 }, + {} +}; + +static const struct nvc0_graph_init +nvf0_graph_init_l1c_0[] = { { 0x419c98, 1, 0x04, 0x00000000 }, { 0x419ca8, 1, 0x04, 0x00000000 }, { 0x419cb0, 1, 0x04, 0x01000000 }, @@ -139,7 +112,11 @@ nvf0_graph_init_tpc[] = { { 0x419cc0, 2, 0x04, 0x00000000 }, { 0x419c80, 1, 0x04, 0x00020230 }, { 0x419ccc, 2, 0x04, 0x00000000 }, - { 0x419c0c, 1, 0x04, 0x00000000 }, + {} +}; + +const struct nvc0_graph_init +nvf0_graph_init_sm_0[] = { { 0x419e00, 1, 0x04, 0x00000080 }, { 0x419ea0, 1, 0x04, 0x00000000 }, { 0x419ee4, 1, 0x04, 0x00000000 }, @@ -155,6 +132,44 @@ nvf0_graph_init_tpc[] = { {} }; +static const struct nvc0_graph_pack +nvf0_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 }, + { nvf0_graph_init_l1c_0 }, + { nvc0_graph_init_mpc_0 }, + { nvf0_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 + ******************************************************************************/ + static int nvf0_graph_fini(struct nouveau_object *object, bool suspend) { @@ -192,25 +207,6 @@ nvf0_graph_fini(struct nouveau_object *object, bool suspend) return nouveau_graph_fini(&priv->base, suspend); } -static struct nvc0_graph_init * -nvf0_graph_init_mmio[] = { - nve4_graph_init_regs, - nvf0_graph_init_unk40xx, - nvc0_graph_init_unk44xx, - nvc0_graph_init_unk78xx, - nvc0_graph_init_unk60xx, - nvd9_graph_init_unk64xx, - nvf0_graph_init_unk58xx, - nvc0_graph_init_unk80xx, - nvf0_graph_init_unk70xx, - nvf0_graph_init_unk5bxx, - nvf0_graph_init_gpc, - nvf0_graph_init_tpc, - nve4_graph_init_unk, - nve4_graph_init_unk88xx, - NULL -}; - #include "fuc/hubnvf0.fuc.h" static struct nvc0_graph_ucode @@ -242,7 +238,7 @@ nvf0_graph_oclass = &(struct nvc0_graph_oclass) { }, .cclass = &nvf0_grctx_oclass, .sclass = nvf0_graph_sclass, - .mmio = nvf0_graph_init_mmio, + .mmio = nvf0_graph_pack_mmio, .fecs.ucode = &nvf0_graph_fecs_ucode, .gpccs.ucode = &nvf0_graph_gpccs_ucode, }.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c index 5ce686ee729..f3b4d9dbf23 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c @@ -124,7 +124,7 @@ nv50_software_sclass[] = { ******************************************************************************/ static int -nv50_software_vblsem_release(void *data, int head) +nv50_software_vblsem_release(void *data, u32 type, int head) { struct nv50_software_chan *chan = data; struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; @@ -183,7 +183,7 @@ nv50_software_context_ctor(struct nouveau_object *parent, return -ENOMEM; for (i = 0; i < chan->vblank.nr_event; i++) { - ret = nouveau_event_new(pdisp->vblank, i, pclass->vblank, + ret = nouveau_event_new(pdisp->vblank, 1, i, pclass->vblank, chan, &chan->vblank.event[i]); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h index 2de370c2127..bb49a7a2085 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h @@ -19,7 +19,7 @@ int nv50_software_ctor(struct nouveau_object *, struct nouveau_object *, struct nv50_software_cclass { struct nouveau_oclass base; - int (*vblank)(void *, int); + int (*vblank)(void *, u32, int); }; struct nv50_software_chan { diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c index f9430c1bf3e..135c20f3835 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c @@ -104,7 +104,7 @@ nvc0_software_sclass[] = { ******************************************************************************/ static int -nvc0_software_vblsem_release(void *data, int head) +nvc0_software_vblsem_release(void *data, u32 type, int head) { struct nv50_software_chan *chan = data; struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; diff --git a/drivers/gpu/drm/nouveau/core/engine/xtensa.c b/drivers/gpu/drm/nouveau/core/engine/xtensa.c index 5f6ede7c489..92384759d2f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/xtensa.c +++ b/drivers/gpu/drm/nouveau/core/engine/xtensa.c @@ -112,7 +112,7 @@ _nouveau_xtensa_init(struct nouveau_object *object) snprintf(name, sizeof(name), "nouveau/nv84_xuc%03x", xtensa->addr >> 12); - ret = request_firmware(&fw, name, &device->pdev->dev); + ret = request_firmware(&fw, name, nv_device_base(device)); if (ret) { nv_warn(xtensa, "unable to load firmware %s\n", name); return ret; diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index e71a4325e67..e0c812bc884 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -258,6 +258,7 @@ struct nv04_display_scanoutpos { * 9070: NVD0_DISP * 9170: NVE0_DISP * 9270: NVF0_DISP + * 9470: GM107_DISP */ #define NV50_DISP_CLASS 0x00005070 @@ -268,6 +269,7 @@ struct nv04_display_scanoutpos { #define NVD0_DISP_CLASS 0x00009070 #define NVE0_DISP_CLASS 0x00009170 #define NVF0_DISP_CLASS 0x00009270 +#define GM107_DISP_CLASS 0x00009470 #define NV50_DISP_MTHD 0x00000000 #define NV50_DISP_MTHD_HEAD 0x00000003 @@ -293,6 +295,10 @@ struct nv04_display_scanoutpos { #define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f #define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000 #define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff +#define NV94_DISP_SOR_DP_PWR 0x00016000 +#define NV94_DISP_SOR_DP_PWR_STATE 0x00000001 +#define NV94_DISP_SOR_DP_PWR_STATE_OFF 0x00000000 +#define NV94_DISP_SOR_DP_PWR_STATE_ON 0x00000001 #define NV50_DISP_DAC_MTHD 0x00020000 #define NV50_DISP_DAC_MTHD_TYPE 0x0000f000 @@ -342,6 +348,7 @@ struct nv50_display_class { * 907a: NVD0_DISP_CURS * 917a: NVE0_DISP_CURS * 927a: NVF0_DISP_CURS + * 947a: GM107_DISP_CURS */ #define NV50_DISP_CURS_CLASS 0x0000507a @@ -352,6 +359,7 @@ struct nv50_display_class { #define NVD0_DISP_CURS_CLASS 0x0000907a #define NVE0_DISP_CURS_CLASS 0x0000917a #define NVF0_DISP_CURS_CLASS 0x0000927a +#define GM107_DISP_CURS_CLASS 0x0000947a struct nv50_display_curs_class { u32 head; @@ -365,6 +373,7 @@ struct nv50_display_curs_class { * 907b: NVD0_DISP_OIMM * 917b: NVE0_DISP_OIMM * 927b: NVE0_DISP_OIMM + * 947b: GM107_DISP_OIMM */ #define NV50_DISP_OIMM_CLASS 0x0000507b @@ -375,6 +384,7 @@ struct nv50_display_curs_class { #define NVD0_DISP_OIMM_CLASS 0x0000907b #define NVE0_DISP_OIMM_CLASS 0x0000917b #define NVF0_DISP_OIMM_CLASS 0x0000927b +#define GM107_DISP_OIMM_CLASS 0x0000947b struct nv50_display_oimm_class { u32 head; @@ -388,6 +398,7 @@ struct nv50_display_oimm_class { * 907c: NVD0_DISP_SYNC * 917c: NVE0_DISP_SYNC * 927c: NVF0_DISP_SYNC + * 947c: GM107_DISP_SYNC */ #define NV50_DISP_SYNC_CLASS 0x0000507c @@ -398,6 +409,7 @@ struct nv50_display_oimm_class { #define NVD0_DISP_SYNC_CLASS 0x0000907c #define NVE0_DISP_SYNC_CLASS 0x0000917c #define NVF0_DISP_SYNC_CLASS 0x0000927c +#define GM107_DISP_SYNC_CLASS 0x0000947c struct nv50_display_sync_class { u32 pushbuf; @@ -412,6 +424,7 @@ struct nv50_display_sync_class { * 907d: NVD0_DISP_MAST * 917d: NVE0_DISP_MAST * 927d: NVF0_DISP_MAST + * 947d: GM107_DISP_MAST */ #define NV50_DISP_MAST_CLASS 0x0000507d @@ -422,6 +435,7 @@ struct nv50_display_sync_class { #define NVD0_DISP_MAST_CLASS 0x0000907d #define NVE0_DISP_MAST_CLASS 0x0000917d #define NVF0_DISP_MAST_CLASS 0x0000927d +#define GM107_DISP_MAST_CLASS 0x0000947d struct nv50_display_mast_class { u32 pushbuf; @@ -435,6 +449,7 @@ struct nv50_display_mast_class { * 907e: NVD0_DISP_OVLY * 917e: NVE0_DISP_OVLY * 927e: NVF0_DISP_OVLY + * 947e: GM107_DISP_OVLY */ #define NV50_DISP_OVLY_CLASS 0x0000507e @@ -445,6 +460,7 @@ struct nv50_display_mast_class { #define NVD0_DISP_OVLY_CLASS 0x0000907e #define NVE0_DISP_OVLY_CLASS 0x0000917e #define NVF0_DISP_OVLY_CLASS 0x0000927e +#define GM107_DISP_OVLY_CLASS 0x0000947e struct nv50_display_ovly_class { u32 pushbuf; diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h index 7b8ea221b00..a8a9a9cf16c 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/device.h +++ b/drivers/gpu/drm/nouveau/core/include/core/device.h @@ -40,6 +40,7 @@ enum nv_subdev_type { NVDEV_ENGINE_FIRST, NVDEV_ENGINE_DMAOBJ = NVDEV_ENGINE_FIRST, + NVDEV_ENGINE_IFB, NVDEV_ENGINE_FIFO, NVDEV_ENGINE_SW, NVDEV_ENGINE_GR, @@ -65,6 +66,7 @@ struct nouveau_device { struct list_head head; struct pci_dev *pdev; + struct platform_device *platformdev; u64 handle; const char *cfgopt; @@ -84,6 +86,7 @@ struct nouveau_device { NV_C0 = 0xc0, NV_D0 = 0xd0, NV_E0 = 0xe0, + GM100 = 0x110, } card_type; u32 chipset; u32 crystal; @@ -140,4 +143,32 @@ nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub) device->pdev->subsystem_device == sub; } +static inline bool +nv_device_is_pci(struct nouveau_device *device) +{ + return device->pdev != NULL; +} + +static inline struct device * +nv_device_base(struct nouveau_device *device) +{ + return nv_device_is_pci(device) ? &device->pdev->dev : + &device->platformdev->dev; +} + +resource_size_t +nv_device_resource_start(struct nouveau_device *device, unsigned int bar); + +resource_size_t +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); + +void +nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr); + +int +nv_device_get_irq(struct nouveau_device *device, bool stall); + #endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/event.h b/drivers/gpu/drm/nouveau/core/include/core/event.h index 5d539ebff3e..ba3f1a76a81 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/event.h +++ b/drivers/gpu/drm/nouveau/core/include/core/event.h @@ -12,32 +12,33 @@ struct nouveau_eventh { struct nouveau_event *event; struct list_head head; unsigned long flags; + u32 types; int index; - int (*func)(void *, int); + int (*func)(void *, u32, int); void *priv; }; struct nouveau_event { - spinlock_t list_lock; - spinlock_t refs_lock; - void *priv; - void (*enable)(struct nouveau_event *, int index); - void (*disable)(struct nouveau_event *, int index); + int (*check)(struct nouveau_event *, u32 type, int index); + void (*enable)(struct nouveau_event *, int type, int index); + void (*disable)(struct nouveau_event *, int type, int index); + int types_nr; int index_nr; - struct { - struct list_head list; - int refs; - } index[]; + + spinlock_t list_lock; + struct list_head *list; + spinlock_t refs_lock; + int refs[]; }; -int nouveau_event_create(int index_nr, struct nouveau_event **); +int nouveau_event_create(int types_nr, int index_nr, struct nouveau_event **); void nouveau_event_destroy(struct nouveau_event **); -void nouveau_event_trigger(struct nouveau_event *, int index); +void nouveau_event_trigger(struct nouveau_event *, u32 types, int index); -int nouveau_event_new(struct nouveau_event *, int index, - int (*func)(void *, int), void *, +int nouveau_event_new(struct nouveau_event *, u32 types, int index, + int (*func)(void *, u32, int), void *, struct nouveau_eventh **); void nouveau_event_ref(struct nouveau_eventh *, struct nouveau_eventh **); void nouveau_event_get(struct nouveau_eventh *); diff --git a/drivers/gpu/drm/nouveau/core/include/core/namedb.h b/drivers/gpu/drm/nouveau/core/include/core/namedb.h index 8897e088608..f5b5fd8e1fc 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/namedb.h +++ b/drivers/gpu/drm/nouveau/core/include/core/namedb.h @@ -33,7 +33,7 @@ nv_namedb(void *obj) int nouveau_namedb_create_(struct nouveau_object *, struct nouveau_object *, struct nouveau_oclass *, u32 pclass, - struct nouveau_oclass *, u32 engcls, + struct nouveau_oclass *, u64 engcls, int size, void **); int _nouveau_namedb_ctor(struct nouveau_object *, struct nouveau_object *, diff --git a/drivers/gpu/drm/nouveau/core/include/engine/device.h b/drivers/gpu/drm/nouveau/core/include/engine/device.h index b3dd2c4c2f1..672d3c8f414 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/device.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/device.h @@ -3,11 +3,20 @@ #include <core/device.h> -#define nouveau_device_create(p,n,s,c,d,u) \ - nouveau_device_create_((p), (n), (s), (c), (d), sizeof(**u), (void **)u) +struct platform_device; -int nouveau_device_create_(struct pci_dev *, u64 name, const char *sname, - const char *cfg, const char *dbg, int, void **); +enum nv_bus_type { + NOUVEAU_BUS_PCI, + NOUVEAU_BUS_PLATFORM, +}; + +#define nouveau_device_create(p,t,n,s,c,d,u) \ + nouveau_device_create_((void *)(p), (t), (n), (s), (c), (d), \ + sizeof(**u), (void **)u) + +int nouveau_device_create_(void *, enum nv_bus_type type, u64 name, + const char *sname, const char *cfg, const char *dbg, + int, void **); int nv04_identify(struct nouveau_device *); int nv10_identify(struct nouveau_device *); @@ -17,6 +26,7 @@ int nv40_identify(struct nouveau_device *); int nv50_identify(struct nouveau_device *); int nvc0_identify(struct nouveau_device *); int nve0_identify(struct nouveau_device *); +int gm100_identify(struct nouveau_device *); struct nouveau_device *nouveau_device_find(u64 name); diff --git a/drivers/gpu/drm/nouveau/core/include/engine/disp.h b/drivers/gpu/drm/nouveau/core/include/engine/disp.h index 4b21fabfbdd..fde84289680 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/disp.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/disp.h @@ -6,8 +6,19 @@ #include <core/device.h> #include <core/event.h> +enum nvkm_hpd_event { + NVKM_HPD_PLUG = 1, + NVKM_HPD_UNPLUG = 2, + NVKM_HPD_IRQ = 4, + NVKM_HPD = (NVKM_HPD_PLUG | NVKM_HPD_UNPLUG | NVKM_HPD_IRQ) +}; + struct nouveau_disp { struct nouveau_engine base; + + struct list_head outp; + struct nouveau_event *hpd; + struct nouveau_event *vblank; }; @@ -17,33 +28,15 @@ nouveau_disp(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_DISP]; } -#define nouveau_disp_create(p,e,c,h,i,x,d) \ - nouveau_disp_create_((p), (e), (c), (h), (i), (x), \ - sizeof(**d), (void **)d) -#define nouveau_disp_destroy(d) ({ \ - struct nouveau_disp *disp = (d); \ - _nouveau_disp_dtor(nv_object(disp)); \ -}) -#define nouveau_disp_init(d) \ - nouveau_engine_init(&(d)->base) -#define nouveau_disp_fini(d,s) \ - nouveau_engine_fini(&(d)->base, (s)) - -int nouveau_disp_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int heads, - const char *, const char *, int, void **); -void _nouveau_disp_dtor(struct nouveau_object *); -#define _nouveau_disp_init _nouveau_engine_init -#define _nouveau_disp_fini _nouveau_engine_fini - -extern struct nouveau_oclass nv04_disp_oclass; -extern struct nouveau_oclass nv50_disp_oclass; -extern struct nouveau_oclass nv84_disp_oclass; -extern struct nouveau_oclass nva0_disp_oclass; -extern struct nouveau_oclass nv94_disp_oclass; -extern struct nouveau_oclass nva3_disp_oclass; -extern struct nouveau_oclass nvd0_disp_oclass; -extern struct nouveau_oclass nve0_disp_oclass; -extern struct nouveau_oclass nvf0_disp_oclass; +extern struct nouveau_oclass *nv04_disp_oclass; +extern struct nouveau_oclass *nv50_disp_oclass; +extern struct nouveau_oclass *nv84_disp_oclass; +extern struct nouveau_oclass *nva0_disp_oclass; +extern struct nouveau_oclass *nv94_disp_oclass; +extern struct nouveau_oclass *nva3_disp_oclass; +extern struct nouveau_oclass *nvd0_disp_oclass; +extern struct nouveau_oclass *nve0_disp_oclass; +extern struct nouveau_oclass *nvf0_disp_oclass; +extern struct nouveau_oclass *gm107_disp_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h index 26b6b2bb111..b639eb2c74f 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -109,6 +109,7 @@ extern struct nouveau_oclass *nv50_fifo_oclass; extern struct nouveau_oclass *nv84_fifo_oclass; extern struct nouveau_oclass *nvc0_fifo_oclass; extern struct nouveau_oclass *nve0_fifo_oclass; +extern struct nouveau_oclass *gk20a_fifo_oclass; extern struct nouveau_oclass *nv108_fifo_oclass; void nv04_fifo_intr(struct nouveau_subdev *); diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h index 97705618de9..8c1d4772da0 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/graph.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/graph.h @@ -63,13 +63,15 @@ extern struct nouveau_oclass nv40_graph_oclass; extern struct nouveau_oclass nv50_graph_oclass; extern struct nouveau_oclass *nvc0_graph_oclass; extern struct nouveau_oclass *nvc1_graph_oclass; -extern struct nouveau_oclass *nvc3_graph_oclass; +extern struct nouveau_oclass *nvc4_graph_oclass; extern struct nouveau_oclass *nvc8_graph_oclass; extern struct nouveau_oclass *nvd7_graph_oclass; extern struct nouveau_oclass *nvd9_graph_oclass; extern struct nouveau_oclass *nve4_graph_oclass; +extern struct nouveau_oclass *gk20a_graph_oclass; extern struct nouveau_oclass *nvf0_graph_oclass; extern struct nouveau_oclass *nv108_graph_oclass; +extern struct nouveau_oclass *gm107_graph_oclass; extern const struct nouveau_bitfield nv04_graph_nsource[]; extern struct nouveau_ofuncs nv04_graph_ofuncs; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h new file mode 100644 index 00000000000..bba01ab1e04 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h @@ -0,0 +1,23 @@ +#ifndef __NVBIOS_P0260_H__ +#define __NVBIOS_P0260_H__ + +u32 nvbios_P0260Te(struct nouveau_bios *, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz); + +struct nvbios_P0260E { + u32 data; +}; + +u32 nvbios_P0260Ee(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr); +u32 nvbios_P0260Ep(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr, + struct nvbios_P0260E *); + +struct nvbios_P0260X { + u32 data; +}; + +u32 nvbios_P0260Xe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr); +u32 nvbios_P0260Xp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr, + struct nvbios_P0260X *); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h index c1270548fd0..f3930c27cb7 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h @@ -16,12 +16,31 @@ enum dcb_connector_type { DCB_CONNECTOR_eDP = 0x47, DCB_CONNECTOR_HDMI_0 = 0x60, DCB_CONNECTOR_HDMI_1 = 0x61, + DCB_CONNECTOR_HDMI_C = 0x63, DCB_CONNECTOR_DMS59_DP0 = 0x64, DCB_CONNECTOR_DMS59_DP1 = 0x65, DCB_CONNECTOR_NONE = 0xff }; -u16 dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len); +struct nvbios_connT { +}; + +u32 nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); +u32 nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_connT *info); + +struct nvbios_connE { + u8 type; + u8 location; + u8 hpd; + u8 dp; + u8 di; + u8 sr; + u8 lcdid; +}; + +u32 nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr); +u32 nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *hdr, + struct nvbios_connE *info); #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h index 6e54218b55f..728206e2177 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h @@ -17,9 +17,10 @@ u16 nvbios_dpout_match(struct nouveau_bios *, u16 type, u16 mask, struct nvbios_dpout *); struct nvbios_dpcfg { - u8 drv; - u8 pre; - u8 unk; + u8 pc; + u8 dc; + u8 pe; + u8 tx_pu; }; u16 @@ -27,7 +28,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *, u16 outp, u8 idx, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *); u16 -nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 un, u8 vs, u8 pe, +nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 pc, u8 vs, u8 pe, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *); diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h index c5e6d1e6ac1..c086ac6d677 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h @@ -61,6 +61,6 @@ struct nvbios_ramcfg { }; u8 nvbios_ramcfg_count(struct nouveau_bios *); -u8 nvbios_ramcfg_index(struct nouveau_bios *); +u8 nvbios_ramcfg_index(struct nouveau_subdev *); #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h index 083541dbe9c..8dc5051df55 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h @@ -31,6 +31,12 @@ struct nouveau_therm_trip_point { int hysteresis; }; +enum nvbios_therm_fan_mode { + NVBIOS_THERM_FAN_TRIP = 0, + NVBIOS_THERM_FAN_LINEAR = 1, + NVBIOS_THERM_FAN_OTHER = 2, +}; + struct nvbios_therm_fan { u16 pwm_freq; @@ -40,6 +46,7 @@ struct nvbios_therm_fan { u16 bump_period; u16 slow_down_period; + enum nvbios_therm_fan_mode fan_mode; struct nouveau_therm_trip_point trip[NOUVEAU_TEMP_FAN_TRIP_MAX]; u8 nr_fan_trip; u8 linear_min_temp; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 8f4ced75444..c01e29c9f89 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h @@ -77,6 +77,8 @@ struct nouveau_clock { int tstate; /* thermal adjustment (max-) */ int dstate; /* display adjustment (min+) */ + bool allow_reclock; + int (*read)(struct nouveau_clock *, enum nv_clk_src); int (*calc)(struct nouveau_clock *, struct nouveau_cstate *); int (*prog)(struct nouveau_clock *); @@ -106,8 +108,8 @@ struct nouveau_clocks { int mdiv; }; -#define nouveau_clock_create(p,e,o,i,d) \ - nouveau_clock_create_((p), (e), (o), (i), sizeof(**d), (void **)d) +#define nouveau_clock_create(p,e,o,i,r,d) \ + nouveau_clock_create_((p), (e), (o), (i), (r), sizeof(**d), (void **)d) #define nouveau_clock_destroy(p) ({ \ struct nouveau_clock *clk = (p); \ _nouveau_clock_dtor(nv_object(clk)); \ @@ -121,7 +123,7 @@ struct nouveau_clocks { int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *, struct nouveau_oclass *, - struct nouveau_clocks *, int, void **); + struct nouveau_clocks *, bool, int, void **); void _nouveau_clock_dtor(struct nouveau_object *); int _nouveau_clock_init(struct nouveau_object *); #define _nouveau_clock_fini _nouveau_subdev_fini diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h index ed1ac68c38b..e292271a84e 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h @@ -9,6 +9,7 @@ struct nouveau_devinit { bool post; void (*meminit)(struct nouveau_devinit *); int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq); + u32 (*mmio)(struct nouveau_devinit *, u32 addr); }; static inline struct nouveau_devinit * @@ -28,5 +29,6 @@ extern struct nouveau_oclass *nv98_devinit_oclass; extern struct nouveau_oclass *nva3_devinit_oclass; extern struct nouveau_oclass *nvaf_devinit_oclass; extern struct nouveau_oclass *nvc0_devinit_oclass; +extern struct nouveau_oclass *gm107_devinit_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h index d7ecafbae1c..871e73914b2 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h @@ -105,6 +105,8 @@ extern struct nouveau_oclass *nvaa_fb_oclass; extern struct nouveau_oclass *nvaf_fb_oclass; extern struct nouveau_oclass *nvc0_fb_oclass; extern struct nouveau_oclass *nve0_fb_oclass; +extern struct nouveau_oclass *gk20a_fb_oclass; +extern struct nouveau_oclass *gm107_fb_oclass; #include <subdev/bios/ramcfg.h> diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h index c85b9f1579a..612d82ab683 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/gpio.h @@ -8,17 +8,18 @@ #include <subdev/bios.h> #include <subdev/bios/gpio.h> +enum nvkm_gpio_event { + NVKM_GPIO_HI = 1, + NVKM_GPIO_LO = 2, + NVKM_GPIO_TOGGLED = (NVKM_GPIO_HI | NVKM_GPIO_LO), +}; + struct nouveau_gpio { struct nouveau_subdev base; struct nouveau_event *events; - /* hardware interfaces */ void (*reset)(struct nouveau_gpio *, u8 func); - int (*drive)(struct nouveau_gpio *, int line, int dir, int out); - int (*sense)(struct nouveau_gpio *, int line); - - /* software interfaces */ int (*find)(struct nouveau_gpio *, int idx, u8 tag, u8 line, struct dcb_gpio_func *); int (*set)(struct nouveau_gpio *, int idx, u8 tag, u8 line, int state); @@ -31,23 +32,10 @@ nouveau_gpio(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_GPIO]; } -#define nouveau_gpio_create(p,e,o,l,d) \ - nouveau_gpio_create_((p), (e), (o), (l), sizeof(**d), (void **)d) -#define nouveau_gpio_destroy(p) ({ \ - struct nouveau_gpio *gpio = (p); \ - _nouveau_gpio_dtor(nv_object(gpio)); \ -}) -#define nouveau_gpio_fini(p,s) \ - nouveau_subdev_fini(&(p)->base, (s)) - -int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, int, void **); -void _nouveau_gpio_dtor(struct nouveau_object *); -int nouveau_gpio_init(struct nouveau_gpio *); - -extern struct nouveau_oclass nv10_gpio_oclass; -extern struct nouveau_oclass nv50_gpio_oclass; -extern struct nouveau_oclass nvd0_gpio_oclass; -extern struct nouveau_oclass nve0_gpio_oclass; +extern struct nouveau_oclass *nv10_gpio_oclass; +extern struct nouveau_oclass *nv50_gpio_oclass; +extern struct nouveau_oclass *nv92_gpio_oclass; +extern struct nouveau_oclass *nvd0_gpio_oclass; +extern struct nouveau_oclass *nve0_gpio_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h index 7f50a858b16..825f7bb46b6 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h @@ -14,52 +14,41 @@ #define NV_I2C_TYPE_EXTDDC(e) (0x0005 | (e) << 8) #define NV_I2C_TYPE_EXTAUX(e) (0x0006 | (e) << 8) +enum nvkm_i2c_event { + NVKM_I2C_PLUG = 1, + NVKM_I2C_UNPLUG = 2, + NVKM_I2C_IRQ = 4, + NVKM_I2C_DONE = 8, + NVKM_I2C_ANY = (NVKM_I2C_PLUG | + NVKM_I2C_UNPLUG | + NVKM_I2C_IRQ | + NVKM_I2C_DONE), +}; + struct nouveau_i2c_port { struct nouveau_object base; struct i2c_adapter adapter; + struct mutex mutex; struct list_head head; u8 index; + int aux; const struct nouveau_i2c_func *func; }; struct nouveau_i2c_func { - void (*acquire)(struct nouveau_i2c_port *); - void (*release)(struct nouveau_i2c_port *); - void (*drive_scl)(struct nouveau_i2c_port *, int); void (*drive_sda)(struct nouveau_i2c_port *, int); int (*sense_scl)(struct nouveau_i2c_port *); int (*sense_sda)(struct nouveau_i2c_port *); - int (*aux)(struct nouveau_i2c_port *, u8, u32, u8 *, u8); + int (*aux)(struct nouveau_i2c_port *, bool, u8, u32, u8 *, u8); int (*pattern)(struct nouveau_i2c_port *, int pattern); int (*lnk_ctl)(struct nouveau_i2c_port *, int nr, int bw, bool enh); int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe); }; -#define nouveau_i2c_port_create(p,e,o,i,a,f,d) \ - nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \ - sizeof(**d), (void **)d) -#define nouveau_i2c_port_destroy(p) ({ \ - struct nouveau_i2c_port *port = (p); \ - _nouveau_i2c_port_dtor(nv_object(i2c)); \ -}) -#define nouveau_i2c_port_init(p) \ - nouveau_object_init(&(p)->base) -#define nouveau_i2c_port_fini(p,s) \ - nouveau_object_fini(&(p)->base, (s)) - -int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, u8, - const struct i2c_algorithm *, - const struct nouveau_i2c_func *, - int, void **); -void _nouveau_i2c_port_dtor(struct nouveau_object *); -#define _nouveau_i2c_port_init nouveau_object_init -#define _nouveau_i2c_port_fini nouveau_object_fini - struct nouveau_i2c_board_info { struct i2c_board_info dev; u8 udelay; /* set to 0 to use the standard delay */ @@ -67,13 +56,20 @@ struct nouveau_i2c_board_info { struct nouveau_i2c { struct nouveau_subdev base; + struct nouveau_event *ntfy; struct nouveau_i2c_port *(*find)(struct nouveau_i2c *, u8 index); struct nouveau_i2c_port *(*find_type)(struct nouveau_i2c *, u16 type); + int (*acquire_pad)(struct nouveau_i2c_port *, unsigned long timeout); + void (*release_pad)(struct nouveau_i2c_port *); + int (*acquire)(struct nouveau_i2c_port *, unsigned long timeout); + void (*release)(struct nouveau_i2c_port *); int (*identify)(struct nouveau_i2c *, int index, const char *what, struct nouveau_i2c_board_info *, bool (*match)(struct nouveau_i2c_port *, struct i2c_board_info *, void *), void *); + + wait_queue_head_t wait; struct list_head ports; }; @@ -83,37 +79,13 @@ nouveau_i2c(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_I2C]; } -#define nouveau_i2c_create(p,e,o,s,d) \ - nouveau_i2c_create_((p), (e), (o), (s), sizeof(**d), (void **)d) -#define nouveau_i2c_destroy(p) ({ \ - struct nouveau_i2c *i2c = (p); \ - _nouveau_i2c_dtor(nv_object(i2c)); \ -}) -#define nouveau_i2c_init(p) ({ \ - struct nouveau_i2c *i2c = (p); \ - _nouveau_i2c_init(nv_object(i2c)); \ -}) -#define nouveau_i2c_fini(p,s) ({ \ - struct nouveau_i2c *i2c = (p); \ - _nouveau_i2c_fini(nv_object(i2c), (s)); \ -}) - -int nouveau_i2c_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, struct nouveau_oclass *, - int, void **); -void _nouveau_i2c_dtor(struct nouveau_object *); -int _nouveau_i2c_init(struct nouveau_object *); -int _nouveau_i2c_fini(struct nouveau_object *, bool); - -extern struct nouveau_oclass nv04_i2c_oclass; -extern struct nouveau_oclass nv4e_i2c_oclass; -extern struct nouveau_oclass nv50_i2c_oclass; -extern struct nouveau_oclass nv94_i2c_oclass; -extern struct nouveau_oclass nvd0_i2c_oclass; -extern struct nouveau_oclass nouveau_anx9805_sclass[]; - -extern const struct i2c_algorithm nouveau_i2c_bit_algo; -extern const struct i2c_algorithm nouveau_i2c_aux_algo; +extern struct nouveau_oclass *nv04_i2c_oclass; +extern struct nouveau_oclass *nv4e_i2c_oclass; +extern struct nouveau_oclass *nv50_i2c_oclass; +extern struct nouveau_oclass *nv94_i2c_oclass; +extern struct nouveau_oclass *nvd0_i2c_oclass; +extern struct nouveau_oclass *gf117_i2c_oclass; +extern struct nouveau_oclass *nve0_i2c_oclass; static inline int nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg) diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h index 88814f159d8..31df634c0fd 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h @@ -30,5 +30,6 @@ nouveau_ibus(void *obj) extern struct nouveau_oclass nvc0_ibus_oclass; extern struct nouveau_oclass nve0_ibus_oclass; +extern struct nouveau_oclass gk20a_ibus_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h index a1985ed3d58..c9c1950b774 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h @@ -35,6 +35,7 @@ nouveau_ltcg(void *obj) #define _nouveau_ltcg_init _nouveau_subdev_init #define _nouveau_ltcg_fini _nouveau_subdev_fini -extern struct nouveau_oclass nvc0_ltcg_oclass; +extern struct nouveau_oclass *gf100_ltcg_oclass; +extern struct nouveau_oclass *gm107_ltcg_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h index adc88b73d91..72b176831be 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h @@ -12,6 +12,7 @@ struct nouveau_mc_intr { struct nouveau_mc { struct nouveau_subdev base; bool use_msi; + unsigned int irq; }; static inline struct nouveau_mc * @@ -47,6 +48,7 @@ struct nouveau_mc_oclass { extern struct nouveau_oclass *nv04_mc_oclass; extern struct nouveau_oclass *nv40_mc_oclass; extern struct nouveau_oclass *nv44_mc_oclass; +extern struct nouveau_oclass *nv4c_mc_oclass; extern struct nouveau_oclass *nv50_mc_oclass; extern struct nouveau_oclass *nv94_mc_oclass; extern struct nouveau_oclass *nv98_mc_oclass; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index 69891d4a3fe..d4a68179e58 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -31,7 +31,7 @@ struct nouveau_therm { int (*pwm_ctrl)(struct nouveau_therm *, int line, bool); int (*pwm_get)(struct nouveau_therm *, int line, u32 *, u32 *); int (*pwm_set)(struct nouveau_therm *, int line, u32, u32); - int (*pwm_clock)(struct nouveau_therm *); + int (*pwm_clock)(struct nouveau_therm *, int line); int (*fan_get)(struct nouveau_therm *); int (*fan_set)(struct nouveau_therm *, int); diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h index 9ab70dfe5b0..db9be803a87 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h @@ -59,5 +59,6 @@ int nouveau_timer_create_(struct nouveau_object *, struct nouveau_engine *, struct nouveau_oclass *, int size, void **); extern struct nouveau_oclass nv04_timer_oclass; +extern struct nouveau_oclass gk20a_timer_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h index 191e739f30d..d0ced94ca54 100644 --- a/drivers/gpu/drm/nouveau/core/os.h +++ b/drivers/gpu/drm/nouveau/core/os.h @@ -5,6 +5,7 @@ #include <linux/slab.h> #include <linux/mutex.h> #include <linux/pci.h> +#include <linux/platform_device.h> #include <linux/printk.h> #include <linux/bitops.h> #include <linux/firmware.h> @@ -23,17 +24,6 @@ #include <asm/unaligned.h> -static inline int -ffsll(u64 mask) -{ - int i; - for (i = 0; i < 64; i++) { - if (mask & (1ULL << i)) - return i + 1; - } - return 0; -} - #ifndef ioread32_native #ifdef __BIG_ENDIAN #define ioread16_native ioread16be diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c index 7098ddd5467..73b1ed20c8d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c @@ -118,8 +118,10 @@ nouveau_bar_create_(struct nouveau_object *parent, if (ret) return ret; - bar->iomem = ioremap(pci_resource_start(device->pdev, 3), - pci_resource_len(device->pdev, 3)); + if (nv_device_resource_len(device, 3) != 0) + bar->iomem = ioremap(nv_device_resource_start(device, 3), + nv_device_resource_len(device, 3)); + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c index 090d594a21b..f748ba49dfc 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c @@ -139,7 +139,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* BAR3 */ start = 0x0100000000ULL; - limit = start + pci_resource_len(device->pdev, 3); + limit = start + nv_device_resource_len(device, 3); ret = nouveau_vm_new(device, start, limit, start, &vm); if (ret) @@ -173,7 +173,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, /* BAR1 */ start = 0x0000000000ULL; - limit = start + pci_resource_len(device->pdev, 1); + limit = start + nv_device_resource_len(device, 1); ret = nouveau_vm_new(device, start, limit--, start, &vm); if (ret) @@ -231,7 +231,7 @@ static int nv50_bar_init(struct nouveau_object *object) { struct nv50_bar_priv *priv = (void *)object; - int ret; + int ret, i; ret = nouveau_bar_init(&priv->base); if (ret) @@ -249,6 +249,8 @@ nv50_bar_init(struct nouveau_object *object) nv_wr32(priv, 0x001704, 0x40000000 | priv->mem->addr >> 12); nv_wr32(priv, 0x001708, 0x80000000 | priv->bar1->node->offset >> 4); nv_wr32(priv, 0x00170c, 0x80000000 | priv->bar3->node->offset >> 4); + for (i = 0; i < 8; i++) + nv_wr32(priv, 0x001900 + (i * 4), 0x00000000); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c index bac5e754de3..ca8139b9ab2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c @@ -30,14 +30,16 @@ #include "priv.h" +struct nvc0_bar_priv_vm { + struct nouveau_gpuobj *mem; + struct nouveau_gpuobj *pgd; + struct nouveau_vm *vm; +}; + struct nvc0_bar_priv { struct nouveau_bar base; spinlock_t lock; - struct { - struct nouveau_gpuobj *mem; - struct nouveau_gpuobj *pgd; - struct nouveau_vm *vm; - } bar[2]; + struct nvc0_bar_priv_vm bar[2]; }; static int @@ -79,88 +81,87 @@ nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma) } static int -nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) +nvc0_bar_init_vm(struct nvc0_bar_priv *priv, struct nvc0_bar_priv_vm *bar_vm, + int bar_nr) { - struct nouveau_device *device = nv_device(parent); - struct pci_dev *pdev = device->pdev; - struct nvc0_bar_priv *priv; - struct nouveau_gpuobj *mem; + struct nouveau_device *device = nv_device(&priv->base); struct nouveau_vm *vm; + resource_size_t bar_len; int ret; - ret = nouveau_bar_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - /* BAR3 */ ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0, - &priv->bar[0].mem); - mem = priv->bar[0].mem; + &bar_vm->mem); if (ret) return ret; ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0, - &priv->bar[0].pgd); + &bar_vm->pgd); if (ret) return ret; - ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 3), 0, &vm); + bar_len = nv_device_resource_len(device, bar_nr); + + ret = nouveau_vm_new(device, 0, bar_len, 0, &vm); if (ret) return ret; atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]); - ret = nouveau_gpuobj_new(nv_object(priv), NULL, - (pci_resource_len(pdev, 3) >> 12) * 8, - 0x1000, NVOBJ_FLAG_ZERO_ALLOC, - &vm->pgt[0].obj[0]); - vm->pgt[0].refcount[0] = 1; - if (ret) - return ret; + /* + * Bootstrap page table lookup. + */ + if (bar_nr == 3) { + ret = nouveau_gpuobj_new(nv_object(priv), NULL, + (bar_len >> 12) * 8, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC, + &vm->pgt[0].obj[0]); + vm->pgt[0].refcount[0] = 1; + if (ret) + return ret; + } - ret = nouveau_vm_ref(vm, &priv->bar[0].vm, priv->bar[0].pgd); + ret = nouveau_vm_ref(vm, &bar_vm->vm, bar_vm->pgd); nouveau_vm_ref(NULL, &vm, NULL); if (ret) return ret; - nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr)); - nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr)); - nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 3) - 1)); - nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1)); + nv_wo32(bar_vm->mem, 0x0200, lower_32_bits(bar_vm->pgd->addr)); + nv_wo32(bar_vm->mem, 0x0204, upper_32_bits(bar_vm->pgd->addr)); + nv_wo32(bar_vm->mem, 0x0208, lower_32_bits(bar_len - 1)); + nv_wo32(bar_vm->mem, 0x020c, upper_32_bits(bar_len - 1)); - /* BAR1 */ - ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0, - &priv->bar[1].mem); - mem = priv->bar[1].mem; - if (ret) - return ret; + return 0; +} - ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0, - &priv->bar[1].pgd); - if (ret) - return ret; +static int +nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_device *device = nv_device(parent); + struct nvc0_bar_priv *priv; + bool has_bar3 = nv_device_resource_len(device, 3) != 0; + int ret; - ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 1), 0, &vm); + ret = nouveau_bar_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); if (ret) return ret; - atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]); + /* BAR3 */ + if (has_bar3) { + ret = nvc0_bar_init_vm(priv, &priv->bar[0], 3); + if (ret) + return ret; + priv->base.alloc = nouveau_bar_alloc; + priv->base.kmap = nvc0_bar_kmap; + } - ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd); - nouveau_vm_ref(NULL, &vm, NULL); + /* BAR1 */ + ret = nvc0_bar_init_vm(priv, &priv->bar[1], 1); if (ret) return ret; - nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr)); - nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr)); - nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 1) - 1)); - nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 1) - 1)); - - priv->base.alloc = nouveau_bar_alloc; - priv->base.kmap = nvc0_bar_kmap; priv->base.umap = nvc0_bar_umap; priv->base.unmap = nvc0_bar_unmap; priv->base.flush = nv84_bar_flush; @@ -202,7 +203,9 @@ nvc0_bar_init(struct nouveau_object *object) nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12); - nv_wr32(priv, 0x001714, 0xc0000000 | priv->bar[0].mem->addr >> 12); + if (priv->bar[0].mem) + nv_wr32(priv, 0x001714, + 0xc0000000 | priv->bar[0].mem->addr >> 12); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c b/drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c new file mode 100644 index 00000000000..199f4e5f748 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c @@ -0,0 +1,109 @@ +/* + * 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 + */ + +#include <subdev/bios.h> +#include <subdev/bios/bit.h> +#include <subdev/bios/ramcfg.h> +#include <subdev/bios/P0260.h> + +u32 +nvbios_P0260Te(struct nouveau_bios *bios, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz) +{ + struct bit_entry bit_P; + u32 data = 0x00000000; + + if (!bit_entry(bios, 'P', &bit_P)) { + if (bit_P.version == 2 && bit_P.length > 0x63) + data = nv_ro32(bios, bit_P.offset + 0x60); + if (data) { + *ver = nv_ro08(bios, data + 0); + switch (*ver) { + case 0x10: + *hdr = nv_ro08(bios, data + 1); + *cnt = nv_ro08(bios, data + 2); + *len = 4; + *xnr = nv_ro08(bios, data + 3); + *xsz = 4; + return data; + default: + break; + } + } + } + + return 0x00000000; +} + +u32 +nvbios_P0260Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len) +{ + u8 hdr, cnt, xnr, xsz; + u32 data = nvbios_P0260Te(bios, ver, &hdr, &cnt, len, &xnr, &xsz); + if (data && idx < cnt) + return data + hdr + (idx * *len); + return 0x00000000; +} + +u32 +nvbios_P0260Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len, + struct nvbios_P0260E *info) +{ + u32 data = nvbios_P0260Ee(bios, idx, ver, len); + memset(info, 0x00, sizeof(*info)); + switch (!!data * *ver) { + case 0x10: + info->data = nv_ro32(bios, data); + return data; + default: + break; + } + return 0x00000000; +} + +u32 +nvbios_P0260Xe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *xsz) +{ + u8 hdr, cnt, len, xnr; + u32 data = nvbios_P0260Te(bios, ver, &hdr, &cnt, &len, &xnr, xsz); + if (data && idx < xnr) + return data + hdr + (cnt * len) + (idx * *xsz); + return 0x00000000; +} + +u32 +nvbios_P0260Xp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr, + struct nvbios_P0260X *info) +{ + u32 data = nvbios_P0260Xe(bios, idx, ver, hdr); + memset(info, 0x00, sizeof(*info)); + switch (!!data * *ver) { + case 0x10: + info->data = nv_ro32(bios, data); + return data; + default: + break; + } + return 0x00000000; +} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index aa0fbbec7f0..d45704a2c2d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -90,10 +90,26 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios) int i; if (device->card_type >= NV_50) { - if ( device->card_type < NV_C0 || - !(nv_rd32(bios, 0x022500) & 0x00000001)) - addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8; + if (device->card_type >= NV_C0 && device->card_type < GM100) { + if (nv_rd32(bios, 0x022500) & 0x00000001) + return; + } else + if (device->card_type >= GM100) { + if (nv_rd32(bios, 0x021c04) & 0x00000001) + return; + } + + addr = nv_rd32(bios, 0x619f04); + if (!(addr & 0x00000008)) { + nv_debug(bios, "... not enabled\n"); + return; + } + if ( (addr & 0x00000003) != 1) { + nv_debug(bios, "... not in vram\n"); + return; + } + addr = (addr & 0xffffff00) << 8; if (!addr) { addr = (u64)nv_rd32(bios, 0x001700) << 16; addr += 0xf0000; @@ -130,6 +146,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) u16 pcir; int i; + /* there is no prom on nv4x IGP's */ + if (device->card_type == NV_40 && device->chipset >= 0x4c) + return; + /* enable access to rom */ if (device->card_type >= NV_50) pcireg = 0x088050; @@ -137,6 +157,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) pcireg = 0x001850; access = nv_mask(bios, pcireg, 0x00000001, 0x00000000); + /* WARNING: PROM accesses should always be 32-bits aligned. Other + * accesses work on most chipset but do not on Kepler chipsets + */ + /* bail if no rom signature, with a workaround for a PROM reading * issue on some chipsets. the first read after a period of * inactivity returns the wrong result, so retry the first header @@ -144,31 +168,35 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) */ i = 16; do { - if (nv_rd08(bios, 0x300000) == 0x55) + u32 data = le32_to_cpu(nv_rd32(bios, 0x300000)) & 0xffff; + if (data == 0xaa55) break; } while (i--); - if (!i || nv_rd08(bios, 0x300001) != 0xaa) - goto out; - - /* additional check (see note below) - read PCI record header */ - pcir = nv_rd08(bios, 0x300018) | - nv_rd08(bios, 0x300019) << 8; - if (nv_rd08(bios, 0x300000 + pcir) != 'P' || - nv_rd08(bios, 0x300001 + pcir) != 'C' || - nv_rd08(bios, 0x300002 + pcir) != 'I' || - nv_rd08(bios, 0x300003 + pcir) != 'R') + if (!i) goto out; /* read entire bios image to system memory */ - bios->size = nv_rd08(bios, 0x300002) * 512; + bios->size = (le32_to_cpu(nv_rd32(bios, 0x300000)) >> 16) & 0xff; + bios->size = bios->size * 512; if (!bios->size) goto out; bios->data = kmalloc(bios->size, GFP_KERNEL); - if (bios->data) { - for (i = 0; i < bios->size; i++) - nv_wo08(bios, i, nv_rd08(bios, 0x300000 + i)); + if (!bios->data) + goto out; + + for (i = 0; i < bios->size; i += 4) + ((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i); + + /* check the PCI record header */ + pcir = nv_ro16(bios, 0x0018); + if (bios->data[pcir + 0] != 'P' || + bios->data[pcir + 1] != 'C' || + bios->data[pcir + 2] != 'I' || + bios->data[pcir + 3] != 'R') { + bios->size = 0; + kfree(bios->data); } out: diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c b/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c index 5ac010efd95..2ede3bcd96a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/conn.c @@ -28,12 +28,12 @@ #include <subdev/bios/dcb.h> #include <subdev/bios/conn.h> -u16 -dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) +u32 +nvbios_connTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { - u16 dcb = dcb_table(bios, ver, hdr, cnt, len); + u32 dcb = dcb_table(bios, ver, hdr, cnt, len); if (dcb && *ver >= 0x30 && *hdr >= 0x16) { - u16 data = nv_ro16(bios, dcb + 0x14); + u32 data = nv_ro16(bios, dcb + 0x14); if (data) { *ver = nv_ro08(bios, data + 0); *hdr = nv_ro08(bios, data + 1); @@ -42,15 +42,59 @@ dcb_conntab(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) return data; } } - return 0x0000; + return 0x00000000; } -u16 -dcb_conn(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) +u32 +nvbios_connTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, + struct nvbios_connT *info) +{ + u32 data = nvbios_connTe(bios, ver, hdr, cnt, len); + memset(info, 0x00, sizeof(*info)); + switch (!!data * *ver) { + case 0x30: + case 0x40: + return data; + default: + break; + } + return 0x00000000; +} + +u32 +nvbios_connEe(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len) { u8 hdr, cnt; - u16 data = dcb_conntab(bios, ver, &hdr, &cnt, len); + u32 data = nvbios_connTe(bios, ver, &hdr, &cnt, len); if (data && idx < cnt) return data + hdr + (idx * *len); - return 0x0000; + return 0x00000000; +} + +u32 +nvbios_connEp(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, + struct nvbios_connE *info) +{ + u32 data = nvbios_connEe(bios, idx, ver, len); + memset(info, 0x00, sizeof(*info)); + switch (!!data * *ver) { + case 0x30: + case 0x40: + info->type = nv_ro08(bios, data + 0x00); + info->location = nv_ro08(bios, data + 0x01) & 0x0f; + info->hpd = (nv_ro08(bios, data + 0x01) & 0x30) >> 4; + info->dp = (nv_ro08(bios, data + 0x01) & 0xc0) >> 6; + if (*len < 4) + return data; + info->hpd |= (nv_ro08(bios, data + 0x02) & 0x03) << 2; + info->dp |= nv_ro08(bios, data + 0x02) & 0x0c; + info->di = (nv_ro08(bios, data + 0x02) & 0xf0) >> 4; + info->hpd |= (nv_ro08(bios, data + 0x03) & 0x07) << 4; + info->sr = (nv_ro08(bios, data + 0x03) & 0x08) >> 3; + info->lcdid = (nv_ro08(bios, data + 0x03) & 0x70) >> 4; + return data; + default: + break; + } + return 0x00000000; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 2d9b9d7a799..88606bfaf84 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c @@ -142,9 +142,36 @@ dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len, if (*ver >= 0x40) { u32 conf = nv_ro32(bios, dcb + 0x04); switch (outp->type) { + case DCB_OUTPUT_DP: + switch (conf & 0x00e00000) { + case 0x00000000: + outp->dpconf.link_bw = 0x06; + break; + case 0x00200000: + outp->dpconf.link_bw = 0x0a; + break; + case 0x00400000: + default: + outp->dpconf.link_bw = 0x14; + break; + } + + switch (conf & 0x0f000000) { + case 0x0f000000: + outp->dpconf.link_nr = 4; + break; + case 0x03000000: + outp->dpconf.link_nr = 2; + break; + case 0x01000000: + default: + outp->dpconf.link_nr = 1; + break; + } + + /* fall-through... */ case DCB_OUTPUT_TMDS: case DCB_OUTPUT_LVDS: - case DCB_OUTPUT_DP: outp->link = (conf & 0x00000030) >> 4; outp->sorconf.link = outp->link; /*XXX*/ outp->extdev = 0x00; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c index 7628fe75922..f309dd65725 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c @@ -162,18 +162,20 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx, struct nvbios_dpcfg *info) { u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len); + memset(info, 0x00, sizeof(*info)); if (data) { switch (*ver) { case 0x21: - info->drv = nv_ro08(bios, data + 0x02); - info->pre = nv_ro08(bios, data + 0x03); - info->unk = nv_ro08(bios, data + 0x04); + info->dc = nv_ro08(bios, data + 0x02); + info->pe = nv_ro08(bios, data + 0x03); + info->tx_pu = nv_ro08(bios, data + 0x04); break; case 0x30: case 0x40: - info->drv = nv_ro08(bios, data + 0x01); - info->pre = nv_ro08(bios, data + 0x02); - info->unk = nv_ro08(bios, data + 0x03); + info->pc = nv_ro08(bios, data + 0x00); + info->dc = nv_ro08(bios, data + 0x01); + info->pe = nv_ro08(bios, data + 0x02); + info->tx_pu = nv_ro08(bios, data + 0x03); break; default: data = 0x0000; @@ -184,7 +186,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx, } u16 -nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe, +nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_dpcfg *info) { @@ -193,16 +195,15 @@ nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe, if (*ver >= 0x30) { const u8 vsoff[] = { 0, 4, 7, 9 }; - idx = (un * 10) + vsoff[vs] + pe; + idx = (pc * 10) + vsoff[vs] + pe; } else { - while ((data = nvbios_dpcfg_entry(bios, outp, idx, + while ((data = nvbios_dpcfg_entry(bios, outp, ++idx, ver, hdr, cnt, len))) { if (nv_ro08(bios, data + 0x00) == vs && nv_ro08(bios, data + 0x01) == pe) break; - idx++; } } - return nvbios_dpcfg_parse(bios, outp, pe, ver, hdr, cnt, len, info); + return nvbios_dpcfg_parse(bios, outp, idx, ver, hdr, cnt, len, info); } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index de201baeb05..626380f9e4c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -98,15 +98,16 @@ static u8 init_conn(struct nvbios_init *init) { struct nouveau_bios *bios = init->bios; - u8 ver, len; - u16 conn; + struct nvbios_connE connE; + u8 ver, hdr; + u32 conn; if (init_exec(init)) { if (init->outp) { conn = init->outp->connector; - conn = dcb_conn(bios, conn, &ver, &len); + conn = nvbios_connEp(bios, conn, &ver, &hdr, &connE); if (conn) - return nv_ro08(bios, conn); + return connE.type; } error("script needs connector type\n"); @@ -118,6 +119,8 @@ init_conn(struct nvbios_init *init) static inline u32 init_nvreg(struct nvbios_init *init, u32 reg) { + struct nouveau_devinit *devinit = nouveau_devinit(init->bios); + /* C51 (at least) sometimes has the lower bits set which the VBIOS * interprets to mean that access needs to go through certain IO * ports instead. The NVIDIA binary driver has been seen to access @@ -147,6 +150,9 @@ init_nvreg(struct nvbios_init *init, u32 reg) if (reg & ~0x00fffffc) warn("unknown bits in register 0x%08x\n", reg); + + if (devinit->mmio) + reg = devinit->mmio(devinit, reg); return reg; } @@ -154,7 +160,7 @@ static u32 init_rd32(struct nvbios_init *init, u32 reg) { reg = init_nvreg(init, reg); - if (init_exec(init)) + if (reg != ~0 && init_exec(init)) return nv_rd32(init->subdev, reg); return 0x00000000; } @@ -163,7 +169,7 @@ static void init_wr32(struct nvbios_init *init, u32 reg, u32 val) { reg = init_nvreg(init, reg); - if (init_exec(init)) + if (reg != ~0 && init_exec(init)) nv_wr32(init->subdev, reg, val); } @@ -171,7 +177,7 @@ static u32 init_mask(struct nvbios_init *init, u32 reg, u32 mask, u32 val) { reg = init_nvreg(init, reg); - if (init_exec(init)) { + if (reg != ~0 && init_exec(init)) { u32 tmp = nv_rd32(init->subdev, reg); nv_wr32(init->subdev, reg, (tmp & ~mask) | val); return tmp; @@ -410,7 +416,7 @@ init_ram_restrict(struct nvbios_init *init) * in case *not* re-reading the strap causes similar breakage. */ if (!init->ramcfg || init->bios->version.major < 0x70) - init->ramcfg = 0x80000000 | nvbios_ramcfg_index(init->bios); + init->ramcfg = 0x80000000 | nvbios_ramcfg_index(init->subdev); return (init->ramcfg & 0x7fffffff); } @@ -845,9 +851,8 @@ init_idx_addr_latched(struct nvbios_init *init) u32 data = nv_ro32(bios, init->offset + 13); u8 count = nv_ro08(bios, init->offset + 17); - trace("INDEX_ADDRESS_LATCHED\t" - "R[0x%06x] : R[0x%06x]\n\tCTRL &= 0x%08x |= 0x%08x\n", - creg, dreg, mask, data); + trace("INDEX_ADDRESS_LATCHED\tR[0x%06x] : R[0x%06x]\n", creg, dreg); + trace("\tCTRL &= 0x%08x |= 0x%08x\n", mask, data); init->offset += 18; while (count--) { diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c b/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c index 991aedda999..6c401f70ab9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c @@ -27,9 +27,9 @@ #include <subdev/bios/ramcfg.h> static u8 -nvbios_ramcfg_strap(struct nouveau_bios *bios) +nvbios_ramcfg_strap(struct nouveau_subdev *subdev) { - return (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2; + return (nv_rd32(subdev, 0x101000) & 0x0000003c) >> 2; } u8 @@ -48,9 +48,10 @@ nvbios_ramcfg_count(struct nouveau_bios *bios) } u8 -nvbios_ramcfg_index(struct nouveau_bios *bios) +nvbios_ramcfg_index(struct nouveau_subdev *subdev) { - u8 strap = nvbios_ramcfg_strap(bios); + struct nouveau_bios *bios = nouveau_bios(subdev); + u8 strap = nvbios_ramcfg_strap(subdev); u32 xlat = 0x00000000; struct bit_entry bit_M; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c index 22ac6dbd6c8..d1585409407 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c @@ -164,6 +164,7 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios, i = 0; fan->nr_fan_trip = 0; + fan->fan_mode = NVBIOS_THERM_FAN_OTHER; while ((entry = nvbios_therm_entry(bios, i++, &ver, &len))) { s16 value = nv_ro16(bios, entry + 1); @@ -174,6 +175,8 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios, break; case 0x24: fan->nr_fan_trip++; + if (fan->fan_mode > NVBIOS_THERM_FAN_TRIP) + fan->fan_mode = NVBIOS_THERM_FAN_TRIP; cur_trip = &fan->trip[fan->nr_fan_trip - 1]; cur_trip->hysteresis = value & 0xf; cur_trip->temp = (value & 0xff0) >> 4; @@ -194,11 +197,19 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios, fan->slow_down_period = value; break; case 0x46: + if (fan->fan_mode > NVBIOS_THERM_FAN_LINEAR) + fan->fan_mode = NVBIOS_THERM_FAN_LINEAR; fan->linear_min_temp = nv_ro08(bios, entry + 1); fan->linear_max_temp = nv_ro08(bios, entry + 2); break; } } + /* starting from fermi, fan management is always linear */ + if (nv_device(bios)->card_type >= NV_C0 && + fan->fan_mode == NVBIOS_THERM_FAN_OTHER) { + fan->fan_mode = NVBIOS_THERM_FAN_LINEAR; + } + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c b/drivers/gpu/drm/nouveau/core/subdev/clock/base.c index dd62baead39..22351f594d2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/base.c @@ -346,8 +346,8 @@ nouveau_clock_ustate_update(struct nouveau_clock *clk, int req) struct nouveau_pstate *pstate; int i = 0; - /* YKW repellant */ - return -ENOSYS; + if (!clk->allow_reclock) + return -ENOSYS; if (req != -1 && req != -2) { list_for_each_entry(pstate, &clk->states, head) { @@ -456,6 +456,7 @@ nouveau_clock_create_(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, struct nouveau_clocks *clocks, + bool allow_reclock, int length, void **object) { struct nouveau_device *device = nv_device(parent); @@ -478,6 +479,8 @@ nouveau_clock_create_(struct nouveau_object *parent, ret = nouveau_pstate_new(clk, idx++); } while (ret == 0); + clk->allow_reclock = allow_reclock; + mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen); if (mode) { if (!strncasecmpz(mode, "disabled", arglen)) { diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c index b74db6cfc4e..eb2d4425a49 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c @@ -82,7 +82,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv04_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, false, + &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c index db7346f7908..8a9e1683979 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c @@ -213,7 +213,8 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv40_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, true, + &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c index 250a6d96016..8c132772ba9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c @@ -507,7 +507,7 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, int ret; ret = nouveau_clock_create(parent, engine, oclass, pclass->domains, - &priv); + false, &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index 4f5a1373f00..9fb58354a80 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c @@ -302,7 +302,8 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nva3_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, false, + &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c index 7a723b4f564..6a65fc9e966 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c @@ -421,7 +421,8 @@ nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvaa_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, &priv); + ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, true, + &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index c3105720ed2..dbf8517f54d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -437,7 +437,8 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvc0_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, false, + &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c index d3c37c96f0e..0e62a324014 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c @@ -307,7 +307,6 @@ calc_clk(struct nve0_clock_priv *priv, info->dsrc = src0; if (div0) { info->ddiv |= 0x80000000; - info->ddiv |= div0 << 8; info->ddiv |= div0; } if (div1D) { @@ -352,7 +351,7 @@ nve0_clock_prog_0(struct nve0_clock_priv *priv, int clk) { struct nve0_clock_info *info = &priv->eng[clk]; if (!info->ssel) { - nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv); + nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x8000003f, info->ddiv); nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc); } } @@ -389,7 +388,10 @@ static void nve0_clock_prog_3(struct nve0_clock_priv *priv, int clk) { struct nve0_clock_info *info = &priv->eng[clk]; - nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv); + if (info->ssel) + nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f00, info->mdiv); + else + nv_mask(priv, 0x137250 + (clk * 0x04), 0x0000003f, info->mdiv); } static void @@ -473,7 +475,8 @@ nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nve0_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, true, + &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c index 8fa34e8152c..239acfe876c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c @@ -96,5 +96,6 @@ nouveau_devinit_create_(struct nouveau_object *parent, devinit->post = nouveau_boolopt(device->cfgopt, "NvForcePost", false); devinit->meminit = impl->meminit; devinit->pll_set = impl->pll_set; + devinit->mmio = impl->mmio; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h index 6b56a0f4cb4..4fe49cf4c99 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/fbmem.h @@ -24,6 +24,8 @@ * */ +#include <core/device.h> + #define NV04_PFB_BOOT_0 0x00100000 # define NV04_PFB_BOOT_0_RAM_AMOUNT 0x00000003 # define NV04_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 @@ -60,10 +62,10 @@ # define NV10_PFB_REFCTRL_VALID_1 (1 << 31) static inline struct io_mapping * -fbmem_init(struct pci_dev *pdev) +fbmem_init(struct nouveau_device *dev) { - return io_mapping_create_wc(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1)); + return io_mapping_create_wc(nv_device_resource_start(dev, 1), + nv_device_resource_len(dev, 1)); } static inline void diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c new file mode 100644 index 00000000000..c69bc7f54e3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c @@ -0,0 +1,56 @@ +/* + * 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 + */ + +#include "nv50.h" + +static u64 +gm107_devinit_disable(struct nouveau_devinit *devinit) +{ + struct nv50_devinit_priv *priv = (void *)devinit; + u32 r021c00 = nv_rd32(priv, 0x021c00); + u32 r021c04 = nv_rd32(priv, 0x021c04); + u64 disable = 0ULL; + + if (r021c00 & 0x00000001) + disable |= (1ULL << NVDEV_ENGINE_COPY0); + if (r021c00 & 0x00000004) + disable |= (1ULL << NVDEV_ENGINE_COPY2); + if (r021c04 & 0x00000001) + disable |= (1ULL << NVDEV_ENGINE_DISP); + + return disable; +} + +struct nouveau_oclass * +gm107_devinit_oclass = &(struct nouveau_devinit_impl) { + .base.handle = NV_SUBDEV(DEVINIT, 0x07), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_devinit_ctor, + .dtor = _nouveau_devinit_dtor, + .init = nv50_devinit_init, + .fini = _nouveau_devinit_fini, + }, + .pll_set = nvc0_devinit_pll_set, + .disable = gm107_devinit_disable, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c index 7037eae46e4..052ad690b46 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c @@ -38,7 +38,7 @@ nv04_devinit_meminit(struct nouveau_devinit *devinit) int i; /* Map the framebuffer aperture */ - fb = fbmem_init(nv_device(priv)->pdev); + fb = fbmem_init(nv_device(priv)); if (!fb) { nv_error(priv, "failed to map fb\n"); return; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c index 98b7e6780dc..4a19c10e517 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c @@ -53,7 +53,7 @@ nv05_devinit_meminit(struct nouveau_devinit *devinit) int i, v; /* Map the framebuffer aperture */ - fb = fbmem_init(nv_device(priv)->pdev); + fb = fbmem_init(nv_device(priv)); if (!fb) { nv_error(priv, "failed to map fb\n"); return; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c index 32b3d2131a7..3b8d657da27 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c @@ -46,7 +46,7 @@ nv10_devinit_meminit(struct nouveau_devinit *devinit) mem_width_count = 2; /* Map the framebuffer aperture */ - fb = fbmem_init(nv_device(priv)->pdev); + fb = fbmem_init(nv_device(priv)); if (!fb) { nv_error(priv, "failed to map fb\n"); return; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c index 4689ba303b0..04bc9732644 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c @@ -37,7 +37,7 @@ nv20_devinit_meminit(struct nouveau_devinit *devinit) struct io_mapping *fb; /* Map the framebuffer aperture */ - fb = fbmem_init(nv_device(priv)->pdev); + fb = fbmem_init(nv_device(priv)); if (!fb) { nv_error(priv, "failed to map fb\n"); return; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h index 141c27e9f18..51d5076333e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h @@ -5,6 +5,7 @@ struct nv50_devinit_priv { struct nouveau_devinit base; + u32 r001540; }; int nv50_devinit_ctor(struct nouveau_object *, struct nouveau_object *, @@ -15,4 +16,6 @@ int nv50_devinit_pll_set(struct nouveau_devinit *, u32, u32); int nva3_devinit_pll_set(struct nouveau_devinit *, u32, u32); +int nvc0_devinit_pll_set(struct nouveau_devinit *, u32, u32); + #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c index 6dedf1dad7f..006cf348bda 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c @@ -81,6 +81,55 @@ nva3_devinit_disable(struct nouveau_devinit *devinit) return disable; } +static u32 +nva3_devinit_mmio_part[] = { + 0x100720, 0x1008bc, 4, + 0x100a20, 0x100adc, 4, + 0x100d80, 0x100ddc, 4, + 0x110000, 0x110f9c, 4, + 0x111000, 0x11103c, 8, + 0x111080, 0x1110fc, 4, + 0x111120, 0x1111fc, 4, + 0x111300, 0x1114bc, 4, + 0, +}; + +static u32 +nva3_devinit_mmio(struct nouveau_devinit *devinit, u32 addr) +{ + struct nv50_devinit_priv *priv = (void *)devinit; + u32 *mmio = nva3_devinit_mmio_part; + + /* the init tables on some boards have INIT_RAM_RESTRICT_ZM_REG_GROUP + * instructions which touch registers that may not even exist on + * some configurations (Quadro 400), which causes the register + * interface to screw up for some amount of time after attempting to + * write to one of these, and results in all sorts of things going + * horribly wrong. + * + * the binary driver avoids touching these registers at all, however, + * the video bios doesn't care and does what the scripts say. it's + * presumed that the io-port access to priv registers isn't effected + * by the screw-up bug mentioned above. + * + * really, a new opcode should've been invented to handle these + * requirements, but whatever, it's too late for that now. + */ + while (mmio[0]) { + if (addr >= mmio[0] && addr <= mmio[1]) { + u32 part = (addr / mmio[2]) & 7; + if (!priv->r001540) + priv->r001540 = nv_rd32(priv, 0x001540); + if (part >= hweight8((priv->r001540 >> 16) & 0xff)) + return ~0; + return addr; + } + mmio += 3; + } + + return addr; +} + struct nouveau_oclass * nva3_devinit_oclass = &(struct nouveau_devinit_impl) { .base.handle = NV_SUBDEV(DEVINIT, 0xa3), @@ -92,4 +141,5 @@ nva3_devinit_oclass = &(struct nouveau_devinit_impl) { }, .pll_set = nva3_devinit_pll_set, .disable = nva3_devinit_disable, + .mmio = nva3_devinit_mmio, }.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c index fa7e63766b1..30c765747ee 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c @@ -24,7 +24,7 @@ #include "nv50.h" -static int +int nvc0_devinit_pll_set(struct nouveau_devinit *devinit, u32 type, u32 freq) { struct nv50_devinit_priv *priv = (void *)devinit; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h index 822a2fbf44a..f0e8683ad84 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h @@ -11,6 +11,7 @@ struct nouveau_devinit_impl { void (*meminit)(struct nouveau_devinit *); int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq); u64 (*disable)(struct nouveau_devinit *); + u32 (*mmio)(struct nouveau_devinit *, u32); }; #define nouveau_devinit_create(p,e,o,d) \ diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c new file mode 100644 index 00000000000..a16024a7477 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "nvc0.h" + +struct gk20a_fb_priv { + struct nouveau_fb base; +}; + +static int +gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct gk20a_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass * +gk20a_fb_oclass = &(struct nouveau_fb_impl) { + .base.handle = NV_SUBDEV(FB, 0xea), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = gk20a_fb_ctor, + .dtor = _nouveau_fb_dtor, + .init = _nouveau_fb_init, + .fini = _nouveau_fb_fini, + }, + .memtype = nvc0_fb_memtype_valid, + .ram = &gk20a_ram_oclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gm107.c new file mode 100644 index 00000000000..c4840aedc2d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gm107.c @@ -0,0 +1,38 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nvc0.h" + +struct nouveau_oclass * +gm107_fb_oclass = &(struct nouveau_fb_impl) { + .base.handle = NV_SUBDEV(FB, 0x07), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_fb_ctor, + .dtor = nvc0_fb_dtor, + .init = nvc0_fb_init, + .fini = _nouveau_fb_fini, + }, + .memtype = nvc0_fb_memtype_valid, + .ram = &gm107_ram_oclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c index 9159a5ccee9..265d1253624 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c @@ -36,7 +36,7 @@ nv1a_fb_oclass = &(struct nv04_fb_impl) { .fini = _nouveau_fb_fini, }, .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv10_ram_oclass, + .base.ram = &nv1a_ram_oclass, .tile.regions = 8, .tile.init = nv10_fb_tile_init, .tile.fini = nv10_fb_tile_fini, diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index cbc7f00c127..1fc55c1e91a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -250,10 +250,8 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); if (priv->r100c08_page) { - priv->r100c08 = pci_map_page(device->pdev, priv->r100c08_page, - 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(device->pdev, priv->r100c08)) + priv->r100c08 = nv_device_map_page(device, priv->r100c08_page); + if (!priv->r100c08) nv_warn(priv, "failed 0x100c08 page map\n"); } else { nv_warn(priv, "failed 0x100c08 page alloc\n"); @@ -270,8 +268,7 @@ nv50_fb_dtor(struct nouveau_object *object) struct nv50_fb_priv *priv = (void *)object; if (priv->r100c08_page) { - pci_unmap_page(device->pdev, priv->r100c08, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); + nv_device_unmap_page(device, priv->r100c08); __free_page(priv->r100c08_page); } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index 45470e1f038..0670ae33ee4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c @@ -70,8 +70,7 @@ nvc0_fb_dtor(struct nouveau_object *object) struct nvc0_fb_priv *priv = (void *)object; if (priv->r100c10_page) { - pci_unmap_page(device->pdev, priv->r100c10, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); + nv_device_unmap_page(device, priv->r100c10); __free_page(priv->r100c10_page); } @@ -94,10 +93,8 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); if (priv->r100c10_page) { - priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, - 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(device->pdev, priv->r100c10)) + priv->r100c10 = nv_device_map_page(device, priv->r100c10_page); + if (!priv->r100c10) return -EFAULT; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h index 9e1931eb746..705a06d755a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h @@ -18,12 +18,14 @@ int nvc0_fb_init(struct nouveau_object *); bool nvc0_fb_memtype_valid(struct nouveau_fb *, u32); -#define nvc0_ram_create(p,e,o,d) \ - nvc0_ram_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nvc0_ram_create(p,e,o,m,d) \ + nvc0_ram_create_((p), (e), (o), (m), sizeof(**d), (void **)d) int nvc0_ram_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); + struct nouveau_oclass *, u32, int, void **); int nvc0_ram_get(struct nouveau_fb *, u64, u32, u32, u32, struct nouveau_mem **); void nvc0_ram_put(struct nouveau_fb *, struct nouveau_mem **); +int nve0_ram_init(struct nouveau_object*); + #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h index edaf95dee61..82273f832e4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h @@ -32,6 +32,8 @@ extern struct nouveau_oclass nva3_ram_oclass; extern struct nouveau_oclass nvaa_ram_oclass; extern struct nouveau_oclass nvc0_ram_oclass; extern struct nouveau_oclass nve0_ram_oclass; +extern struct nouveau_oclass gk20a_ram_oclass; +extern struct nouveau_oclass gm107_ram_oclass; int nouveau_sddr3_calc(struct nouveau_ram *ram); int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts); diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h index 0f57fcfe0bb..2af9cfd2c60 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h @@ -26,7 +26,7 @@ ramfuc_reg2(u32 addr1, u32 addr2) }; } -static inline struct ramfuc_reg +static noinline struct ramfuc_reg ramfuc_reg(u32 addr) { return ramfuc_reg2(addr, addr); @@ -107,7 +107,7 @@ ramfuc_nsec(struct ramfuc *ram, u32 nsec) #define ram_init(s,p) ramfuc_init(&(s)->base, (p)) #define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) -#define ram_have(s,r) ((s)->r_##r.addr != 0x000000) +#define ram_have(s,r) ((s)->r_##r.addr[0] != 0x000000) #define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) #define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) #define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c new file mode 100644 index 00000000000..4d77d75e467 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include "priv.h" + +#include <subdev/fb.h> + +struct gk20a_mem { + struct nouveau_mem base; + void *cpuaddr; + dma_addr_t handle; +}; +#define to_gk20a_mem(m) container_of(m, struct gk20a_mem, base) + +static void +gk20a_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) +{ + struct device *dev = nv_device_base(nv_device(pfb)); + struct gk20a_mem *mem = to_gk20a_mem(*pmem); + + *pmem = NULL; + if (unlikely(mem == NULL)) + return; + + if (likely(mem->cpuaddr)) + dma_free_coherent(dev, mem->base.size << PAGE_SHIFT, + mem->cpuaddr, mem->handle); + + kfree(mem->base.pages); + kfree(mem); +} + +static int +gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, + u32 memtype, struct nouveau_mem **pmem) +{ + struct device *dev = nv_device_base(nv_device(pfb)); + struct gk20a_mem *mem; + u32 type = memtype & 0xff; + u32 npages, order; + int i; + + nv_debug(pfb, "%s: size: %llx align: %x, ncmin: %x\n", __func__, size, + align, ncmin); + + npages = size >> PAGE_SHIFT; + if (npages == 0) + npages = 1; + + if (align == 0) + align = PAGE_SIZE; + align >>= PAGE_SHIFT; + + /* round alignment to the next power of 2, if needed */ + order = fls(align); + if ((align & (align - 1)) == 0) + order--; + align = BIT(order); + + /* ensure returned address is correctly aligned */ + npages = max(align, npages); + + mem = kzalloc(sizeof(*mem), GFP_KERNEL); + if (!mem) + return -ENOMEM; + + mem->base.size = npages; + mem->base.memtype = type; + + mem->base.pages = kzalloc(sizeof(dma_addr_t) * npages, GFP_KERNEL); + if (!mem->base.pages) { + kfree(mem); + return -ENOMEM; + } + + *pmem = &mem->base; + + mem->cpuaddr = dma_alloc_coherent(dev, npages << PAGE_SHIFT, + &mem->handle, GFP_KERNEL); + if (!mem->cpuaddr) { + nv_error(pfb, "%s: cannot allocate memory!\n", __func__); + gk20a_ram_put(pfb, pmem); + return -ENOMEM; + } + + align <<= PAGE_SHIFT; + + /* alignment check */ + if (unlikely(mem->handle & (align - 1))) + nv_warn(pfb, "memory not aligned as requested: %pad (0x%x)\n", + &mem->handle, align); + + nv_debug(pfb, "alloc size: 0x%x, align: 0x%x, paddr: %pad, vaddr: %p\n", + npages << PAGE_SHIFT, align, &mem->handle, mem->cpuaddr); + + for (i = 0; i < npages; i++) + mem->base.pages[i] = mem->handle + (PAGE_SIZE * i); + + mem->base.offset = (u64)mem->base.pages[0]; + + return 0; +} + +static int +gk20a_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 datasize, + struct nouveau_object **pobject) +{ + struct nouveau_ram *ram; + int ret; + + ret = nouveau_ram_create(parent, engine, oclass, &ram); + *pobject = nv_object(ram); + if (ret) + return ret; + ram->type = NV_MEM_TYPE_STOLEN; + ram->size = get_num_physpages() << PAGE_SHIFT; + + ram->get = gk20a_ram_get; + ram->put = gk20a_ram_put; + + return 0; +} + +struct nouveau_oclass +gk20a_ram_oclass = { + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = gk20a_ram_ctor, + .dtor = _nouveau_ram_dtor, + .init = _nouveau_ram_init, + .fini = _nouveau_ram_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgm107.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramgm107.c new file mode 100644 index 00000000000..4c6363595c7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramgm107.c @@ -0,0 +1,56 @@ +/* + * 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 + */ + +#include "nvc0.h" + +struct gm107_ram { + struct nouveau_ram base; +}; + +static int +gm107_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct gm107_ram *ram; + int ret; + + ret = nvc0_ram_create(parent, engine, oclass, 0x021c14, &ram); + *pobject = nv_object(ram); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass +gm107_ram_oclass = { + .handle = 0, + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = gm107_ram_ctor, + .dtor = _nouveau_ram_dtor, + .init = nve0_ram_init, + .fini = _nouveau_ram_fini, + } +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c index c7fdb3a9e88..e5d12c24cc4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c @@ -91,7 +91,7 @@ nv50_ram_calc(struct nouveau_fb *pfb, u32 freq) } while (perfE.memory < freq); /* locate specific data set for the attached memory */ - strap = nvbios_ramcfg_index(bios); + strap = nvbios_ramcfg_index(nv_subdev(pfb)); if (strap >= cnt) { nv_error(pfb, "invalid ramcfg strap\n"); return -EINVAL; @@ -211,7 +211,7 @@ nv50_ram_prog(struct nouveau_fb *pfb) struct nv50_ram *ram = (void *)pfb->ram; struct nv50_ramseq *hwsq = &ram->hwsq; - ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); + ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", true)); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c index f4ae8aa46a2..8076fb195dd 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c @@ -98,7 +98,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) } /* locate specific data set for the attached memory */ - strap = nvbios_ramcfg_index(bios); + strap = nvbios_ramcfg_index(nv_subdev(pfb)); if (strap >= cnt) { nv_error(pfb, "invalid ramcfg strap\n"); return -EINVAL; @@ -309,7 +309,7 @@ nva3_ram_prog(struct nouveau_fb *pfb) struct nouveau_device *device = nv_device(pfb); struct nva3_ram *ram = (void *)pfb->ram; struct nva3_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); + ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true)); return 0; } @@ -335,21 +335,23 @@ nva3_ram_init(struct nouveau_object *object) /* prepare for ddr link training, and load training patterns */ switch (ram->base.type) { case NV_MEM_TYPE_DDR3: { - static const u32 pattern[16] = { - 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, - 0x00000000, 0x11111111, 0x44444444, 0xdddddddd, - 0x33333333, 0x55555555, 0x77777777, 0x66666666, - 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb, - }; - - nv_wr32(pfb, 0x100538, 0x10001ff6); /*XXX*/ - nv_wr32(pfb, 0x1005a8, 0x0000ffff); - nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001); - for (i = 0; i < 0x30; i++) { - nv_wr32(pfb, 0x10f8c0, (i << 8) | i); - nv_wr32(pfb, 0x10f8e0, (i << 8) | i); - nv_wr32(pfb, 0x10f900, pattern[i % 16]); - nv_wr32(pfb, 0x10f920, pattern[i % 16]); + if (nv_device(pfb)->chipset == 0xa8) { + static const u32 pattern[16] = { + 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, + 0x00000000, 0x11111111, 0x44444444, 0xdddddddd, + 0x33333333, 0x55555555, 0x77777777, 0x66666666, + 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb, + }; + + nv_wr32(pfb, 0x100538, 0x10001ff6); /*XXX*/ + nv_wr32(pfb, 0x1005a8, 0x0000ffff); + nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001); + for (i = 0; i < 0x30; i++) { + nv_wr32(pfb, 0x10f8c0, (i << 8) | i); + nv_wr32(pfb, 0x10f8e0, (i << 8) | i); + nv_wr32(pfb, 0x10f900, pattern[i % 16]); + nv_wr32(pfb, 0x10f920, pattern[i % 16]); + } } } break; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c index 0391b824ee7..5a6a5027f74 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c @@ -152,7 +152,7 @@ nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq) } /* locate specific data set for the attached memory */ - strap = nvbios_ramcfg_index(bios); + strap = nvbios_ramcfg_index(nv_subdev(pfb)); if (strap >= cnt) { nv_error(pfb, "invalid ramcfg strap\n"); return -EINVAL; @@ -408,7 +408,7 @@ nvc0_ram_prog(struct nouveau_fb *pfb) struct nouveau_device *device = nv_device(pfb); struct nvc0_ram *ram = (void *)pfb->ram; struct nvc0_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); + ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true)); return 0; } @@ -505,7 +505,8 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, int nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int size, void **pobject) + struct nouveau_oclass *oclass, u32 maskaddr, int size, + void **pobject) { struct nouveau_fb *pfb = nouveau_fb(parent); struct nouveau_bios *bios = nouveau_bios(pfb); @@ -513,7 +514,7 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ u32 parts = nv_rd32(pfb, 0x022438); - u32 pmask = nv_rd32(pfb, 0x022554); + u32 pmask = nv_rd32(pfb, maskaddr); u32 bsize = nv_rd32(pfb, 0x10f20c); u32 offset, length; bool uniform = true; @@ -630,7 +631,7 @@ nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvc0_ram *ram; int ret; - ret = nvc0_ram_create(parent, engine, oclass, &ram); + ret = nvc0_ram_create(parent, engine, oclass, 0x022554, &ram); *pobject = nv_object(ram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c index 3257c522a02..c5b46e30231 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c @@ -200,6 +200,7 @@ r1373f4_init(struct nve0_ramfuc *fuc) /* (re)program mempll, if required */ if (ram->mode == 2) { ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000); + ram_mask(fuc, 0x132000, 0x80000000, 0x80000000); ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); ram_mask(fuc, 0x132004, 0x103fffff, mcoef); ram_mask(fuc, 0x132000, 0x00000001, 0x00000001); @@ -262,8 +263,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) struct nve0_ram *ram = (void *)pfb->ram; struct nve0_ramfuc *fuc = &ram->fuc; struct nouveau_ram_data *next = ram->base.next; - int vc = !(next->bios.ramcfg_11_02_08); - int mv = !(next->bios.ramcfg_11_02_04); + int vc = !next->bios.ramcfg_11_02_08; + int mv = !next->bios.ramcfg_11_02_04; u32 mask, data; ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000); @@ -370,8 +371,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) } } - if ( (next->bios.ramcfg_11_02_40) || - (next->bios.ramcfg_11_07_10)) { + if (next->bios.ramcfg_11_02_40 || + next->bios.ramcfg_11_07_10) { ram_mask(fuc, 0x132040, 0x00010000, 0x00010000); ram_nsec(fuc, 20000); } @@ -417,7 +418,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ram_mask(fuc, 0x10f694, 0xff00ff00, data); } - if (ram->mode == 2 && (next->bios.ramcfg_11_08_10)) + if (ram->mode == 2 && next->bios.ramcfg_11_08_10) data = 0x00000080; else data = 0x00000000; @@ -425,13 +426,13 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) mask = 0x00070000; data = 0x00000000; - if (!(next->bios.ramcfg_11_02_80)) + if (!next->bios.ramcfg_11_02_80) data |= 0x03000000; - if (!(next->bios.ramcfg_11_02_40)) + if (!next->bios.ramcfg_11_02_40) data |= 0x00002000; - if (!(next->bios.ramcfg_11_07_10)) + if (!next->bios.ramcfg_11_07_10) data |= 0x00004000; - if (!(next->bios.ramcfg_11_07_08)) + if (!next->bios.ramcfg_11_07_08) data |= 0x00000003; else data |= 0x74000000; @@ -486,7 +487,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) data = mask = 0x00000000; if (NOTE00(ramcfg_02_03 != 0)) { - data |= (next->bios.ramcfg_11_02_03) << 8; + data |= next->bios.ramcfg_11_02_03 << 8; mask |= 0x00000300; } if (NOTE00(ramcfg_01_10)) { @@ -498,7 +499,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) data = mask = 0x00000000; if (NOTE00(timing_30_07 != 0)) { - data |= (next->bios.timing_20_30_07) << 28; + data |= next->bios.timing_20_30_07 << 28; mask |= 0x70000000; } if (NOTE00(ramcfg_01_01)) { @@ -510,7 +511,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) data = mask = 0x00000000; if (NOTE00(timing_30_07 != 0)) { - data |= (next->bios.timing_20_30_07) << 28; + data |= next->bios.timing_20_30_07 << 28; mask |= 0x70000000; } if (NOTE00(ramcfg_01_02)) { @@ -522,16 +523,16 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) mask = 0x33f00000; data = 0x00000000; - if (!(next->bios.ramcfg_11_01_04)) + if (!next->bios.ramcfg_11_01_04) data |= 0x20200000; - if (!(next->bios.ramcfg_11_07_80)) + if (!next->bios.ramcfg_11_07_80) data |= 0x12800000; /*XXX: see note above about there probably being some condition * for the 10f824 stuff that uses ramcfg 3... */ - if ( (next->bios.ramcfg_11_03_f0)) { + if (next->bios.ramcfg_11_03_f0) { if (next->bios.rammap_11_08_0c) { - if (!(next->bios.ramcfg_11_07_80)) + if (!next->bios.ramcfg_11_07_80) mask |= 0x00000020; else data |= 0x00000020; @@ -563,7 +564,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000); } - data = (next->bios.timing_20_30_07) << 8; + data = next->bios.timing_20_30_07 << 8; if (next->bios.ramcfg_11_01_01) data |= 0x80000000; ram_mask(fuc, 0x100778, 0x00000700, data); @@ -588,7 +589,7 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */ - if ((next->bios.ramcfg_11_08_10) && (ram->mode == 2) /*XXX*/) { + if (next->bios.ramcfg_11_08_10 && (ram->mode == 2) /*XXX*/) { u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000); nve0_ram_train(fuc, 0xbc0e0000, 0xa4010000); /*XXX*/ ram_nsec(fuc, 1000); @@ -621,8 +622,8 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) data = ram_rd32(fuc, 0x10f978); data &= ~0x00046144; data |= 0x0000000b; - if (!(next->bios.ramcfg_11_07_08)) { - if (!(next->bios.ramcfg_11_07_04)) + if (!next->bios.ramcfg_11_07_08) { + if (!next->bios.ramcfg_11_07_04) data |= 0x0000200c; else data |= 0x00000000; @@ -636,11 +637,11 @@ nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) ram_wr32(fuc, 0x10f830, data); } - if (!(next->bios.ramcfg_11_07_08)) { + if (!next->bios.ramcfg_11_07_08) { data = 0x88020000; - if ( (next->bios.ramcfg_11_07_04)) + if ( next->bios.ramcfg_11_07_04) data |= 0x10000000; - if (!(next->bios.rammap_11_08_10)) + if (!next->bios.rammap_11_08_10) data |= 0x00080000; } else { data = 0xa40e0000; @@ -689,8 +690,8 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) const u32 runk0 = ram->fN1 << 16; const u32 runk1 = ram->fN1; struct nouveau_ram_data *next = ram->base.next; - int vc = !(next->bios.ramcfg_11_02_08); - int mv = !(next->bios.ramcfg_11_02_04); + int vc = !next->bios.ramcfg_11_02_08; + int mv = !next->bios.ramcfg_11_02_04; u32 mask, data; ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000); @@ -705,7 +706,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) } ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000); - if ((next->bios.ramcfg_11_03_f0)) + if (next->bios.ramcfg_11_03_f0) ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000); ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ @@ -761,7 +762,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010); data = ram_rd32(fuc, 0x1373ec) & ~0x00030000; - data |= (next->bios.ramcfg_11_03_30) << 12; + data |= next->bios.ramcfg_11_03_30 << 16; ram_wr32(fuc, 0x1373ec, data); ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000); ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000); @@ -793,8 +794,8 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) } } - if ( (next->bios.ramcfg_11_02_40) || - (next->bios.ramcfg_11_07_10)) { + if (next->bios.ramcfg_11_02_40 || + next->bios.ramcfg_11_07_10) { ram_mask(fuc, 0x132040, 0x00010000, 0x00010000); ram_nsec(fuc, 20000); } @@ -810,13 +811,13 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) mask = 0x00010000; data = 0x00000000; - if (!(next->bios.ramcfg_11_02_80)) + if (!next->bios.ramcfg_11_02_80) data |= 0x03000000; - if (!(next->bios.ramcfg_11_02_40)) + if (!next->bios.ramcfg_11_02_40) data |= 0x00002000; - if (!(next->bios.ramcfg_11_07_10)) + if (!next->bios.ramcfg_11_07_10) data |= 0x00004000; - if (!(next->bios.ramcfg_11_07_08)) + if (!next->bios.ramcfg_11_07_08) data |= 0x00000003; else data |= 0x14000000; @@ -844,16 +845,16 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) mask = 0x33f00000; data = 0x00000000; - if (!(next->bios.ramcfg_11_01_04)) + if (!next->bios.ramcfg_11_01_04) data |= 0x20200000; - if (!(next->bios.ramcfg_11_07_80)) + if (!next->bios.ramcfg_11_07_80) data |= 0x12800000; /*XXX: see note above about there probably being some condition * for the 10f824 stuff that uses ramcfg 3... */ - if ( (next->bios.ramcfg_11_03_f0)) { + if (next->bios.ramcfg_11_03_f0) { if (next->bios.rammap_11_08_0c) { - if (!(next->bios.ramcfg_11_07_80)) + if (!next->bios.ramcfg_11_07_80) mask |= 0x00000020; else data |= 0x00000020; @@ -876,7 +877,7 @@ nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) data = next->bios.timing_20_2c_1fc0; ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24); - ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8); + ram_mask(fuc, 0x10f224, 0x001f0000, next->bios.timing_20_30_f8 << 16); ram_wr32(fuc, 0x10f090, 0x4000007f); ram_nsec(fuc, 1000); @@ -950,10 +951,11 @@ nve0_ram_calc_data(struct nouveau_fb *pfb, u32 freq, } /* locate specific data set for the attached memory */ + strap = nvbios_ramcfg_index(nv_subdev(pfb)); ram->base.ramcfg.data = nvbios_rammapSp(bios, ram->base.rammap.data, ram->base.rammap.version, - ram->base.rammap.size, cnt, len, - nvbios_ramcfg_index(bios), + ram->base.rammap.size, + cnt, len, strap, &ram->base.ramcfg.version, &ram->base.ramcfg.size, &data->bios); @@ -1110,7 +1112,7 @@ nve0_ram_prog(struct nouveau_fb *pfb) struct nouveau_device *device = nv_device(pfb); struct nve0_ram *ram = (void *)pfb->ram; struct nve0_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); + ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true)); return (ram->base.next == &ram->base.xition); } @@ -1123,7 +1125,7 @@ nve0_ram_tidy(struct nouveau_fb *pfb) ram_exec(fuc, false); } -static int +int nve0_ram_init(struct nouveau_object *object) { struct nouveau_fb *pfb = (void *)object->parent; @@ -1226,7 +1228,7 @@ nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, int ret, i; u32 tmp; - ret = nvc0_ram_create(parent, engine, oclass, &ram); + ret = nvc0_ram_create(parent, engine, oclass, 0x022554, &ram); *pobject = nv_object(ram); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c index f572c2804c3..45e0202f315 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c @@ -22,21 +22,24 @@ * Authors: Ben Skeggs */ -#include <subdev/gpio.h> #include <subdev/bios.h> #include <subdev/bios/gpio.h> +#include "priv.h" + static int nouveau_gpio_drive(struct nouveau_gpio *gpio, int idx, int line, int dir, int out) { - return gpio->drive ? gpio->drive(gpio, line, dir, out) : -ENODEV; + const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; + return impl->drive ? impl->drive(gpio, line, dir, out) : -ENODEV; } static int nouveau_gpio_sense(struct nouveau_gpio *gpio, int idx, int line) { - return gpio->sense ? gpio->sense(gpio, line) : -ENODEV; + const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; + return impl->sense ? impl->sense(gpio, line) : -ENODEV; } static int @@ -102,6 +105,80 @@ nouveau_gpio_get(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line) return ret; } +static void +nouveau_gpio_intr_disable(struct nouveau_event *event, int type, int index) +{ + struct nouveau_gpio *gpio = nouveau_gpio(event->priv); + const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; + impl->intr_mask(gpio, type, 1 << index, 0); +} + +static void +nouveau_gpio_intr_enable(struct nouveau_event *event, int type, int index) +{ + struct nouveau_gpio *gpio = nouveau_gpio(event->priv); + const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; + impl->intr_mask(gpio, type, 1 << index, 1 << index); +} + +static void +nouveau_gpio_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_gpio *gpio = nouveau_gpio(subdev); + const struct nouveau_gpio_impl *impl = (void *)nv_object(gpio)->oclass; + u32 hi, lo, e, i; + + impl->intr_stat(gpio, &hi, &lo); + + for (i = 0; e = 0, (hi | lo) && i < impl->lines; i++) { + if (hi & (1 << i)) + e |= NVKM_GPIO_HI; + if (lo & (1 << i)) + e |= NVKM_GPIO_LO; + nouveau_event_trigger(gpio->events, e, i); + } +} + +int +_nouveau_gpio_fini(struct nouveau_object *object, bool suspend) +{ + const struct nouveau_gpio_impl *impl = (void *)object->oclass; + struct nouveau_gpio *gpio = nouveau_gpio(object); + u32 mask = (1 << impl->lines) - 1; + + impl->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0); + impl->intr_stat(gpio, &mask, &mask); + + return nouveau_subdev_fini(&gpio->base, suspend); +} + +static struct dmi_system_id gpio_reset_ids[] = { + { + .ident = "Apple Macbook 10,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"), + } + }, + { } +}; + +int +_nouveau_gpio_init(struct nouveau_object *object) +{ + struct nouveau_gpio *gpio = nouveau_gpio(object); + int ret; + + ret = nouveau_subdev_init(&gpio->base); + if (ret) + return ret; + + if (gpio->reset && dmi_check_system(gpio_reset_ids)) + gpio->reset(gpio, DCB_GPIO_UNUSED); + + return ret; +} + void _nouveau_gpio_dtor(struct nouveau_object *object) { @@ -113,9 +190,10 @@ _nouveau_gpio_dtor(struct nouveau_object *object) int nouveau_gpio_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int lines, + struct nouveau_oclass *oclass, int length, void **pobject) { + const struct nouveau_gpio_impl *impl = (void *)oclass; struct nouveau_gpio *gpio; int ret; @@ -125,34 +203,34 @@ nouveau_gpio_create_(struct nouveau_object *parent, if (ret) return ret; - ret = nouveau_event_create(lines, &gpio->events); - if (ret) - return ret; - gpio->find = nouveau_gpio_find; gpio->set = nouveau_gpio_set; gpio->get = nouveau_gpio_get; + gpio->reset = impl->reset; + + ret = nouveau_event_create(2, impl->lines, &gpio->events); + if (ret) + return ret; + + gpio->events->priv = gpio; + gpio->events->enable = nouveau_gpio_intr_enable; + gpio->events->disable = nouveau_gpio_intr_disable; + nv_subdev(gpio)->intr = nouveau_gpio_intr; return 0; } -static struct dmi_system_id gpio_reset_ids[] = { - { - .ident = "Apple Macbook 10,1", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"), - } - }, - { } -}; - int -nouveau_gpio_init(struct nouveau_gpio *gpio) +_nouveau_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { - int ret = nouveau_subdev_init(&gpio->base); - if (ret == 0 && gpio->reset) { - if (dmi_check_system(gpio_reset_ids)) - gpio->reset(gpio, DCB_GPIO_UNUSED); - } - return ret; + struct nouveau_gpio *gpio; + int ret; + + ret = nouveau_gpio_create(parent, engine, oclass, &gpio); + *pobject = nv_object(gpio); + if (ret) + return ret; + + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c index 76d5d5465dd..27ad23eaf18 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv10.c @@ -26,10 +26,6 @@ #include "priv.h" -struct nv10_gpio_priv { - struct nouveau_gpio base; -}; - static int nv10_gpio_sense(struct nouveau_gpio *gpio, int line) { @@ -83,95 +79,38 @@ nv10_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) } static void -nv10_gpio_intr(struct nouveau_subdev *subdev) -{ - struct nv10_gpio_priv *priv = (void *)subdev; - u32 intr = nv_rd32(priv, 0x001104); - u32 hi = (intr & 0x0000ffff) >> 0; - u32 lo = (intr & 0xffff0000) >> 16; - int i; - - for (i = 0; (hi | lo) && i < 32; i++) { - if ((hi | lo) & (1 << i)) - nouveau_event_trigger(priv->base.events, i); - } - - nv_wr32(priv, 0x001104, intr); -} - -static void -nv10_gpio_intr_enable(struct nouveau_event *event, int line) -{ - nv_wr32(event->priv, 0x001104, 0x00010001 << line); - nv_mask(event->priv, 0x001144, 0x00010001 << line, 0x00010001 << line); -} - -static void -nv10_gpio_intr_disable(struct nouveau_event *event, int line) -{ - nv_wr32(event->priv, 0x001104, 0x00010001 << line); - nv_mask(event->priv, 0x001144, 0x00010001 << line, 0x00000000); -} - -static int -nv10_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) +nv10_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) { - struct nv10_gpio_priv *priv; - int ret; - - ret = nouveau_gpio_create(parent, engine, oclass, 16, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.drive = nv10_gpio_drive; - priv->base.sense = nv10_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nv10_gpio_intr_enable; - priv->base.events->disable = nv10_gpio_intr_disable; - nv_subdev(priv)->intr = nv10_gpio_intr; - return 0; + u32 intr = nv_rd32(gpio, 0x001104); + u32 stat = nv_rd32(gpio, 0x001144) & intr; + *lo = (stat & 0xffff0000) >> 16; + *hi = (stat & 0x0000ffff); + nv_wr32(gpio, 0x001104, intr); } static void -nv10_gpio_dtor(struct nouveau_object *object) -{ - struct nv10_gpio_priv *priv = (void *)object; - nouveau_gpio_destroy(&priv->base); -} - -static int -nv10_gpio_init(struct nouveau_object *object) -{ - struct nv10_gpio_priv *priv = (void *)object; - int ret; - - ret = nouveau_gpio_init(&priv->base); - if (ret) - return ret; - - nv_wr32(priv, 0x001144, 0x00000000); - nv_wr32(priv, 0x001104, 0xffffffff); - return 0; -} - -static int -nv10_gpio_fini(struct nouveau_object *object, bool suspend) +nv10_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) { - struct nv10_gpio_priv *priv = (void *)object; - nv_wr32(priv, 0x001144, 0x00000000); - return nouveau_gpio_fini(&priv->base, suspend); + u32 inte = nv_rd32(gpio, 0x001144); + if (type & NVKM_GPIO_LO) + inte = (inte & ~(mask << 16)) | (data << 16); + if (type & NVKM_GPIO_HI) + inte = (inte & ~mask) | data; + nv_wr32(gpio, 0x001144, inte); } -struct nouveau_oclass -nv10_gpio_oclass = { - .handle = NV_SUBDEV(GPIO, 0x10), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv10_gpio_ctor, - .dtor = nv10_gpio_dtor, - .init = nv10_gpio_init, - .fini = nv10_gpio_fini, +struct nouveau_oclass * +nv10_gpio_oclass = &(struct nouveau_gpio_impl) { + .base.handle = NV_SUBDEV(GPIO, 0x10), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_gpio_ctor, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, -}; + .lines = 16, + .intr_stat = nv10_gpio_intr_stat, + .intr_mask = nv10_gpio_intr_mask, + .drive = nv10_gpio_drive, + .sense = nv10_gpio_sense, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c index c4c1d415e7f..1864fa98e6b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c @@ -24,15 +24,10 @@ #include "priv.h" -struct nv50_gpio_priv { - struct nouveau_gpio base; -}; - -static void +void nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match) { struct nouveau_bios *bios = nouveau_bios(gpio); - struct nv50_gpio_priv *priv = (void *)gpio; u8 ver, len; u16 entry; int ent = -1; @@ -46,7 +41,8 @@ nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match) u8 unk0 = !!(data & 0x02000000); u8 unk1 = !!(data & 0x04000000); u32 val = (unk1 << 16) | unk0; - u32 reg = regs[line >> 4]; line &= 0x0f; + u32 reg = regs[line >> 4]; + u32 lsh = line & 0x0f; if ( func == DCB_GPIO_UNUSED || (match != DCB_GPIO_UNUSED && match != func)) @@ -54,7 +50,7 @@ nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match) gpio->set(gpio, 0, func, line, defs); - nv_mask(priv, reg, 0x00010001 << line, val << line); + nv_mask(gpio, reg, 0x00010001 << lsh, val << lsh); } } @@ -71,7 +67,7 @@ nv50_gpio_location(int line, u32 *reg, u32 *shift) return 0; } -static int +int nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) { u32 reg, shift; @@ -79,11 +75,11 @@ nv50_gpio_drive(struct nouveau_gpio *gpio, int line, int dir, int out) if (nv50_gpio_location(line, ®, &shift)) return -EINVAL; - nv_mask(gpio, reg, 7 << shift, (((dir ^ 1) << 1) | out) << shift); + nv_mask(gpio, reg, 3 << shift, (((dir ^ 1) << 1) | out) << shift); return 0; } -static int +int nv50_gpio_sense(struct nouveau_gpio *gpio, int line) { u32 reg, shift; @@ -94,119 +90,40 @@ nv50_gpio_sense(struct nouveau_gpio *gpio, int line) return !!(nv_rd32(gpio, reg) & (4 << shift)); } -void -nv50_gpio_intr(struct nouveau_subdev *subdev) -{ - struct nv50_gpio_priv *priv = (void *)subdev; - u32 intr0, intr1 = 0; - u32 hi, lo; - int i; - - intr0 = nv_rd32(priv, 0xe054) & nv_rd32(priv, 0xe050); - if (nv_device(priv)->chipset > 0x92) - intr1 = nv_rd32(priv, 0xe074) & nv_rd32(priv, 0xe070); - - hi = (intr0 & 0x0000ffff) | (intr1 << 16); - lo = (intr0 >> 16) | (intr1 & 0xffff0000); - - for (i = 0; (hi | lo) && i < 32; i++) { - if ((hi | lo) & (1 << i)) - nouveau_event_trigger(priv->base.events, i); - } - - nv_wr32(priv, 0xe054, intr0); - if (nv_device(priv)->chipset > 0x92) - nv_wr32(priv, 0xe074, intr1); -} - -void -nv50_gpio_intr_enable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xe050 : 0xe070; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x04, mask); - nv_mask(event->priv, addr + 0x00, mask, mask); -} - -void -nv50_gpio_intr_disable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xe050 : 0xe070; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x04, mask); - nv_mask(event->priv, addr + 0x00, mask, 0x00000000); -} - -static int -nv50_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_gpio_priv *priv; - int ret; - - ret = nouveau_gpio_create(parent, engine, oclass, - nv_device(parent)->chipset > 0x92 ? 32 : 16, - &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.reset = nv50_gpio_reset; - priv->base.drive = nv50_gpio_drive; - priv->base.sense = nv50_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nv50_gpio_intr_enable; - priv->base.events->disable = nv50_gpio_intr_disable; - nv_subdev(priv)->intr = nv50_gpio_intr; - return 0; -} - -void -nv50_gpio_dtor(struct nouveau_object *object) -{ - struct nv50_gpio_priv *priv = (void *)object; - nouveau_gpio_destroy(&priv->base); -} - -int -nv50_gpio_init(struct nouveau_object *object) +static void +nv50_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) { - struct nv50_gpio_priv *priv = (void *)object; - int ret; - - ret = nouveau_gpio_init(&priv->base); - if (ret) - return ret; - - /* disable, and ack any pending gpio interrupts */ - nv_wr32(priv, 0xe050, 0x00000000); - nv_wr32(priv, 0xe054, 0xffffffff); - if (nv_device(priv)->chipset > 0x92) { - nv_wr32(priv, 0xe070, 0x00000000); - nv_wr32(priv, 0xe074, 0xffffffff); - } - - return 0; + u32 intr = nv_rd32(gpio, 0x00e054); + u32 stat = nv_rd32(gpio, 0x00e050) & intr; + *lo = (stat & 0xffff0000) >> 16; + *hi = (stat & 0x0000ffff); + nv_wr32(gpio, 0x00e054, intr); } -int -nv50_gpio_fini(struct nouveau_object *object, bool suspend) +static void +nv50_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) { - struct nv50_gpio_priv *priv = (void *)object; - nv_wr32(priv, 0xe050, 0x00000000); - if (nv_device(priv)->chipset > 0x92) - nv_wr32(priv, 0xe070, 0x00000000); - return nouveau_gpio_fini(&priv->base, suspend); + u32 inte = nv_rd32(gpio, 0x00e050); + if (type & NVKM_GPIO_LO) + inte = (inte & ~(mask << 16)) | (data << 16); + if (type & NVKM_GPIO_HI) + inte = (inte & ~mask) | data; + nv_wr32(gpio, 0x00e050, inte); } -struct nouveau_oclass -nv50_gpio_oclass = { - .handle = NV_SUBDEV(GPIO, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nv50_gpio_init, - .fini = nv50_gpio_fini, +struct nouveau_oclass * +nv50_gpio_oclass = &(struct nouveau_gpio_impl) { + .base.handle = NV_SUBDEV(GPIO, 0x50), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_gpio_ctor, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, -}; + .lines = 16, + .intr_stat = nv50_gpio_intr_stat, + .intr_mask = nv50_gpio_intr_mask, + .drive = nv50_gpio_drive, + .sense = nv50_gpio_sense, + .reset = nv50_gpio_reset, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c new file mode 100644 index 00000000000..252083d376f --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv92.c @@ -0,0 +1,74 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "priv.h" + +void +nv92_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) +{ + u32 intr0 = nv_rd32(gpio, 0x00e054); + u32 intr1 = nv_rd32(gpio, 0x00e074); + u32 stat0 = nv_rd32(gpio, 0x00e050) & intr0; + u32 stat1 = nv_rd32(gpio, 0x00e070) & intr1; + *lo = (stat1 & 0xffff0000) | (stat0 >> 16); + *hi = (stat1 << 16) | (stat0 & 0x0000ffff); + nv_wr32(gpio, 0x00e054, intr0); + nv_wr32(gpio, 0x00e074, intr1); +} + +void +nv92_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) +{ + u32 inte0 = nv_rd32(gpio, 0x00e050); + u32 inte1 = nv_rd32(gpio, 0x00e070); + if (type & NVKM_GPIO_LO) + inte0 = (inte0 & ~(mask << 16)) | (data << 16); + if (type & NVKM_GPIO_HI) + inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); + mask >>= 16; + data >>= 16; + if (type & NVKM_GPIO_LO) + inte1 = (inte1 & ~(mask << 16)) | (data << 16); + if (type & NVKM_GPIO_HI) + inte1 = (inte1 & ~mask) | data; + nv_wr32(gpio, 0x00e050, inte0); + nv_wr32(gpio, 0x00e070, inte1); +} + +struct nouveau_oclass * +nv92_gpio_oclass = &(struct nouveau_gpio_impl) { + .base.handle = NV_SUBDEV(GPIO, 0x92), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_gpio_ctor, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, + }, + .lines = 32, + .intr_stat = nv92_gpio_intr_stat, + .intr_mask = nv92_gpio_intr_mask, + .drive = nv50_gpio_drive, + .sense = nv50_gpio_sense, + .reset = nv50_gpio_reset, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c index 010431e3ace..a4682b0956a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nvd0.c @@ -24,15 +24,10 @@ #include "priv.h" -struct nvd0_gpio_priv { - struct nouveau_gpio base; -}; - void nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match) { struct nouveau_bios *bios = nouveau_bios(gpio); - struct nvd0_gpio_priv *priv = (void *)gpio; u8 ver, len; u16 entry; int ent = -1; @@ -51,9 +46,9 @@ nvd0_gpio_reset(struct nouveau_gpio *gpio, u8 match) gpio->set(gpio, 0, func, line, defs); - nv_mask(priv, 0x00d610 + (line * 4), 0xff, unk0); + nv_mask(gpio, 0x00d610 + (line * 4), 0xff, unk0); if (unk1--) - nv_mask(priv, 0x00d740 + (unk1 * 4), 0xff, line); + nv_mask(gpio, 0x00d740 + (unk1 * 4), 0xff, line); } } @@ -72,36 +67,19 @@ nvd0_gpio_sense(struct nouveau_gpio *gpio, int line) return !!(nv_rd32(gpio, 0x00d610 + (line * 4)) & 0x00004000); } -static int -nvd0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvd0_gpio_priv *priv; - int ret; - - ret = nouveau_gpio_create(parent, engine, oclass, 32, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.reset = nvd0_gpio_reset; - priv->base.drive = nvd0_gpio_drive; - priv->base.sense = nvd0_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nv50_gpio_intr_enable; - priv->base.events->disable = nv50_gpio_intr_disable; - nv_subdev(priv)->intr = nv50_gpio_intr; - return 0; -} - -struct nouveau_oclass -nvd0_gpio_oclass = { - .handle = NV_SUBDEV(GPIO, 0xd0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nv50_gpio_init, - .fini = nv50_gpio_fini, +struct nouveau_oclass * +nvd0_gpio_oclass = &(struct nouveau_gpio_impl) { + .base.handle = NV_SUBDEV(GPIO, 0xd0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_gpio_ctor, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, -}; + .lines = 32, + .intr_stat = nv92_gpio_intr_stat, + .intr_mask = nv92_gpio_intr_mask, + .drive = nvd0_gpio_drive, + .sense = nvd0_gpio_sense, + .reset = nvd0_gpio_reset, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c index 16b8c5bf5ef..e1145b48c76 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c @@ -24,108 +24,51 @@ #include "priv.h" -struct nve0_gpio_priv { - struct nouveau_gpio base; -}; - -void -nve0_gpio_intr(struct nouveau_subdev *subdev) +static void +nve0_gpio_intr_stat(struct nouveau_gpio *gpio, u32 *hi, u32 *lo) { - struct nve0_gpio_priv *priv = (void *)subdev; - u32 intr0 = nv_rd32(priv, 0xdc00) & nv_rd32(priv, 0xdc08); - u32 intr1 = nv_rd32(priv, 0xdc80) & nv_rd32(priv, 0xdc88); - u32 hi = (intr0 & 0x0000ffff) | (intr1 << 16); - u32 lo = (intr0 >> 16) | (intr1 & 0xffff0000); - int i; - - for (i = 0; (hi | lo) && i < 32; i++) { - if ((hi | lo) & (1 << i)) - nouveau_event_trigger(priv->base.events, i); - } - - nv_wr32(priv, 0xdc00, intr0); - nv_wr32(priv, 0xdc88, intr1); + u32 intr0 = nv_rd32(gpio, 0x00dc00); + u32 intr1 = nv_rd32(gpio, 0x00dc80); + u32 stat0 = nv_rd32(gpio, 0x00dc08) & intr0; + u32 stat1 = nv_rd32(gpio, 0x00dc88) & intr1; + *lo = (stat1 & 0xffff0000) | (stat0 >> 16); + *hi = (stat1 << 16) | (stat0 & 0x0000ffff); + nv_wr32(gpio, 0x00dc00, intr0); + nv_wr32(gpio, 0x00dc80, intr1); } void -nve0_gpio_intr_enable(struct nouveau_event *event, int line) +nve0_gpio_intr_mask(struct nouveau_gpio *gpio, u32 type, u32 mask, u32 data) { - const u32 addr = line < 16 ? 0xdc00 : 0xdc80; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x08, mask); - nv_mask(event->priv, addr + 0x00, mask, mask); -} - -void -nve0_gpio_intr_disable(struct nouveau_event *event, int line) -{ - const u32 addr = line < 16 ? 0xdc00 : 0xdc80; - const u32 mask = 0x00010001 << (line & 0xf); - nv_wr32(event->priv, addr + 0x08, mask); - nv_mask(event->priv, addr + 0x00, mask, 0x00000000); -} - -int -nve0_gpio_fini(struct nouveau_object *object, bool suspend) -{ - struct nve0_gpio_priv *priv = (void *)object; - nv_wr32(priv, 0xdc08, 0x00000000); - nv_wr32(priv, 0xdc88, 0x00000000); - return nouveau_gpio_fini(&priv->base, suspend); -} - -int -nve0_gpio_init(struct nouveau_object *object) -{ - struct nve0_gpio_priv *priv = (void *)object; - int ret; - - ret = nouveau_gpio_init(&priv->base); - if (ret) - return ret; - - nv_wr32(priv, 0xdc00, 0xffffffff); - nv_wr32(priv, 0xdc80, 0xffffffff); - return 0; -} - -void -nve0_gpio_dtor(struct nouveau_object *object) -{ - struct nve0_gpio_priv *priv = (void *)object; - nouveau_gpio_destroy(&priv->base); -} - -static int -nve0_gpio_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nve0_gpio_priv *priv; - int ret; - - ret = nouveau_gpio_create(parent, engine, oclass, 32, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.reset = nvd0_gpio_reset; - priv->base.drive = nvd0_gpio_drive; - priv->base.sense = nvd0_gpio_sense; - priv->base.events->priv = priv; - priv->base.events->enable = nve0_gpio_intr_enable; - priv->base.events->disable = nve0_gpio_intr_disable; - nv_subdev(priv)->intr = nve0_gpio_intr; - return 0; + u32 inte0 = nv_rd32(gpio, 0x00dc08); + u32 inte1 = nv_rd32(gpio, 0x00dc88); + if (type & NVKM_GPIO_LO) + inte0 = (inte0 & ~(mask << 16)) | (data << 16); + if (type & NVKM_GPIO_HI) + inte0 = (inte0 & ~(mask & 0xffff)) | (data & 0xffff); + mask >>= 16; + data >>= 16; + if (type & NVKM_GPIO_LO) + inte1 = (inte1 & ~(mask << 16)) | (data << 16); + if (type & NVKM_GPIO_HI) + inte1 = (inte1 & ~mask) | data; + nv_wr32(gpio, 0x00dc08, inte0); + nv_wr32(gpio, 0x00dc88, inte1); } -struct nouveau_oclass -nve0_gpio_oclass = { - .handle = NV_SUBDEV(GPIO, 0xe0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nve0_gpio_ctor, - .dtor = nv50_gpio_dtor, - .init = nve0_gpio_init, - .fini = nve0_gpio_fini, +struct nouveau_oclass * +nve0_gpio_oclass = &(struct nouveau_gpio_impl) { + .base.handle = NV_SUBDEV(GPIO, 0xe0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_gpio_ctor, + .dtor = _nouveau_gpio_dtor, + .init = _nouveau_gpio_init, + .fini = _nouveau_gpio_fini, }, -}; + .lines = 32, + .intr_stat = nve0_gpio_intr_stat, + .intr_mask = nve0_gpio_intr_mask, + .drive = nvd0_gpio_drive, + .sense = nvd0_gpio_sense, + .reset = nvd0_gpio_reset, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h b/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h index 2ee1c895c78..e1724dfc86a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/priv.h @@ -3,15 +3,65 @@ #include <subdev/gpio.h> -void nv50_gpio_dtor(struct nouveau_object *); -int nv50_gpio_init(struct nouveau_object *); -int nv50_gpio_fini(struct nouveau_object *, bool); -void nv50_gpio_intr(struct nouveau_subdev *); -void nv50_gpio_intr_enable(struct nouveau_event *, int line); -void nv50_gpio_intr_disable(struct nouveau_event *, int line); +#define nouveau_gpio_create(p,e,o,d) \ + nouveau_gpio_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_gpio_destroy(p) ({ \ + struct nouveau_gpio *gpio = (p); \ + _nouveau_gpio_dtor(nv_object(gpio)); \ +}) +#define nouveau_gpio_init(p) ({ \ + struct nouveau_gpio *gpio = (p); \ + _nouveau_gpio_init(nv_object(gpio)); \ +}) +#define nouveau_gpio_fini(p,s) ({ \ + struct nouveau_gpio *gpio = (p); \ + _nouveau_gpio_fini(nv_object(gpio), (s)); \ +}) + +int nouveau_gpio_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +int _nouveau_gpio_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void _nouveau_gpio_dtor(struct nouveau_object *); +int _nouveau_gpio_init(struct nouveau_object *); +int _nouveau_gpio_fini(struct nouveau_object *, bool); + +struct nouveau_gpio_impl { + struct nouveau_oclass base; + int lines; + + /* read and ack pending interrupts, returning only data + * for lines that have not been masked off, while still + * performing the ack for anything that was pending. + */ + void (*intr_stat)(struct nouveau_gpio *, u32 *, u32 *); + + /* mask on/off interrupts for hi/lo transitions on a + * given set of gpio lines + */ + void (*intr_mask)(struct nouveau_gpio *, u32, u32, u32); + + /* configure gpio direction and output value */ + int (*drive)(struct nouveau_gpio *, int line, int dir, int out); + + /* sense current state of given gpio line */ + int (*sense)(struct nouveau_gpio *, int line); + + /*XXX*/ + void (*reset)(struct nouveau_gpio *, u8); +}; + +void nv50_gpio_reset(struct nouveau_gpio *, u8); +int nv50_gpio_drive(struct nouveau_gpio *, int, int, int); +int nv50_gpio_sense(struct nouveau_gpio *, int); + +void nv92_gpio_intr_stat(struct nouveau_gpio *, u32 *, u32 *); +void nv92_gpio_intr_mask(struct nouveau_gpio *, u32, u32, u32); void nvd0_gpio_reset(struct nouveau_gpio *, u8); int nvd0_gpio_drive(struct nouveau_gpio *, int, int, int); int nvd0_gpio_sense(struct nouveau_gpio *, int); + #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c index 4b195ac4da6..2c2731a6cf9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs <bskeggs@redhat.com> */ -#include <subdev/i2c.h> +#include "port.h" struct anx9805_i2c_port { struct nouveau_i2c_port base; @@ -37,6 +37,8 @@ anx9805_train(struct nouveau_i2c_port *port, int link_nr, int link_bw, bool enh) struct nouveau_i2c_port *mast = (void *)nv_object(chan)->parent; u8 tmp, i; + DBG("ANX9805 train %d 0x%02x %d\n", link_nr, link_bw, enh); + nv_wri2cr(mast, chan->addr, 0xa0, link_bw); nv_wri2cr(mast, chan->addr, 0xa1, link_nr | (enh ? 0x80 : 0x00)); nv_wri2cr(mast, chan->addr, 0xa2, 0x01); @@ -60,21 +62,29 @@ anx9805_train(struct nouveau_i2c_port *port, int link_nr, int link_bw, bool enh) } static int -anx9805_aux(struct nouveau_i2c_port *port, u8 type, u32 addr, u8 *data, u8 size) +anx9805_aux(struct nouveau_i2c_port *port, bool retry, + u8 type, u32 addr, u8 *data, u8 size) { struct anx9805_i2c_port *chan = (void *)port; struct nouveau_i2c_port *mast = (void *)nv_object(chan)->parent; int i, ret = -ETIMEDOUT; + u8 buf[16] = {}; u8 tmp; + DBG("%02x %05x %d\n", type, addr, size); + tmp = nv_rdi2cr(mast, chan->ctrl, 0x07) & ~0x04; nv_wri2cr(mast, chan->ctrl, 0x07, tmp | 0x04); nv_wri2cr(mast, chan->ctrl, 0x07, tmp); nv_wri2cr(mast, chan->ctrl, 0xf7, 0x01); nv_wri2cr(mast, chan->addr, 0xe4, 0x80); - for (i = 0; !(type & 1) && i < size; i++) - nv_wri2cr(mast, chan->addr, 0xf0 + i, data[i]); + if (!(type & 1)) { + memcpy(buf, data, size); + DBG("%16ph", buf); + for (i = 0; i < size; i++) + nv_wri2cr(mast, chan->addr, 0xf0 + i, buf[i]); + } nv_wri2cr(mast, chan->addr, 0xe5, ((size - 1) << 4) | type); nv_wri2cr(mast, chan->addr, 0xe6, (addr & 0x000ff) >> 0); nv_wri2cr(mast, chan->addr, 0xe7, (addr & 0x0ff00) >> 8); @@ -93,8 +103,13 @@ anx9805_aux(struct nouveau_i2c_port *port, u8 type, u32 addr, u8 *data, u8 size) goto done; } - for (i = 0; (type & 1) && i < size; i++) - data[i] = nv_rdi2cr(mast, chan->addr, 0xf0 + i); + if (type & 1) { + for (i = 0; i < size; i++) + buf[i] = nv_rdi2cr(mast, chan->addr, 0xf0 + i); + DBG("%16ph", buf); + memcpy(data, buf, size); + } + ret = 0; done: nv_wri2cr(mast, chan->ctrl, 0xf7, 0x01); diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c index 5de074ad170..02eb42be2e9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/aux.c @@ -22,15 +22,19 @@ * Authors: Ben Skeggs */ -#include <subdev/i2c.h> +#include "priv.h" int nv_rdaux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size) { + struct nouveau_i2c *i2c = nouveau_i2c(port); if (port->func->aux) { - if (port->func->acquire) - port->func->acquire(port); - return port->func->aux(port, 9, addr, data, size); + int ret = i2c->acquire(port, 0); + if (ret == 0) { + ret = port->func->aux(port, true, 9, addr, data, size); + i2c->release(port); + } + return ret; } return -ENODEV; } @@ -38,10 +42,14 @@ nv_rdaux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size) int nv_wraux(struct nouveau_i2c_port *port, u32 addr, u8 *data, u8 size) { + struct nouveau_i2c *i2c = nouveau_i2c(port); if (port->func->aux) { - if (port->func->acquire) - port->func->acquire(port); - return port->func->aux(port, 8, addr, data, size); + int ret = i2c->acquire(port, 0); + if (ret == 0) { + ret = port->func->aux(port, true, 8, addr, data, size); + i2c->release(port); + } + return ret; } return -ENODEV; } @@ -50,13 +58,16 @@ static int aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { struct nouveau_i2c_port *port = adap->algo_data; + struct nouveau_i2c *i2c = nouveau_i2c(port); struct i2c_msg *msg = msgs; int ret, mcnt = num; if (!port->func->aux) return -ENODEV; - if ( port->func->acquire) - port->func->acquire(port); + + ret = i2c->acquire(port, 0); + if (ret) + return ret; while (mcnt--) { u8 remaining = msg->len; @@ -74,9 +85,11 @@ aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if (mcnt || remaining > 16) cmd |= 4; /* MOT */ - ret = port->func->aux(port, cmd, msg->addr, ptr, cnt); - if (ret < 0) + ret = port->func->aux(port, true, cmd, msg->addr, ptr, cnt); + if (ret < 0) { + i2c->release(port); return ret; + } ptr += cnt; remaining -= cnt; @@ -85,6 +98,7 @@ aux_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) msg++; } + i2c->release(port); return num; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index c33c03d2f4a..09ba2cc851c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -23,13 +23,16 @@ */ #include <core/option.h> +#include <core/event.h> #include <subdev/bios.h> #include <subdev/bios/dcb.h> #include <subdev/bios/i2c.h> -#include <subdev/i2c.h> #include <subdev/vga.h> +#include "priv.h" +#include "pad.h" + /****************************************************************************** * interface to linux i2c bit-banging algorithm *****************************************************************************/ @@ -45,9 +48,15 @@ nouveau_i2c_pre_xfer(struct i2c_adapter *adap) { struct i2c_algo_bit_data *bit = adap->algo_data; struct nouveau_i2c_port *port = bit->data; - if (port->func->acquire) - port->func->acquire(port); - return 0; + return nouveau_i2c(port)->acquire(port, bit->timeout); +} + +static void +nouveau_i2c_post_xfer(struct i2c_adapter *adap) +{ + struct i2c_algo_bit_data *bit = adap->algo_data; + struct nouveau_i2c_port *port = bit->data; + return nouveau_i2c(port)->release(port); } static void @@ -82,6 +91,15 @@ nouveau_i2c_getsda(void *data) * base i2c "port" class implementation *****************************************************************************/ +int +_nouveau_i2c_port_fini(struct nouveau_object *object, bool suspend) +{ + struct nouveau_i2c_port *port = (void *)object; + struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port); + nv_ofuncs(pad)->fini(nv_object(pad), suspend); + return nouveau_object_fini(&port->base, suspend); +} + void _nouveau_i2c_port_dtor(struct nouveau_object *object) { @@ -98,7 +116,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, const struct nouveau_i2c_func *func, int size, void **pobject) { - struct nouveau_device *device = nv_device(parent); + struct nouveau_device *device = nv_device(engine); struct nouveau_i2c *i2c = (void *)engine; struct nouveau_i2c_port *port; int ret; @@ -111,10 +129,11 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, snprintf(port->adapter.name, sizeof(port->adapter.name), "nouveau-%s-%d", device->name, index); port->adapter.owner = THIS_MODULE; - port->adapter.dev.parent = &device->pdev->dev; + port->adapter.dev.parent = nv_device_base(device); port->index = index; + port->aux = -1; port->func = func; - i2c_set_adapdata(&port->adapter, i2c); + mutex_init(&port->mutex); if ( algo == &nouveau_i2c_bit_algo && !nouveau_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) { @@ -128,6 +147,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, bit->timeout = usecs_to_jiffies(2200); bit->data = port; bit->pre_xfer = nouveau_i2c_pre_xfer; + bit->post_xfer = nouveau_i2c_post_xfer; bit->setsda = nouveau_i2c_setsda; bit->setscl = nouveau_i2c_setscl; bit->getsda = nouveau_i2c_getsda; @@ -141,7 +161,6 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, ret = i2c_add_adapter(&port->adapter); } - /* drop port's i2c subdev refcount, i2c handles this itself */ if (ret == 0) list_add_tail(&port->head, &i2c->ports); return ret; @@ -193,6 +212,75 @@ nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type) return NULL; } +static void +nouveau_i2c_release_pad(struct nouveau_i2c_port *port) +{ + struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port); + struct nouveau_i2c *i2c = nouveau_i2c(port); + + if (atomic_dec_and_test(&nv_object(pad)->usecount)) { + nv_ofuncs(pad)->fini(nv_object(pad), false); + wake_up_all(&i2c->wait); + } +} + +static int +nouveau_i2c_try_acquire_pad(struct nouveau_i2c_port *port) +{ + struct nvkm_i2c_pad *pad = nvkm_i2c_pad(port); + + if (atomic_add_return(1, &nv_object(pad)->usecount) != 1) { + struct nouveau_object *owner = (void *)pad->port; + do { + if (owner == (void *)port) + return 0; + owner = owner->parent; + } while(owner); + nouveau_i2c_release_pad(port); + return -EBUSY; + } + + pad->next = port; + nv_ofuncs(pad)->init(nv_object(pad)); + return 0; +} + +static int +nouveau_i2c_acquire_pad(struct nouveau_i2c_port *port, unsigned long timeout) +{ + struct nouveau_i2c *i2c = nouveau_i2c(port); + + if (timeout) { + if (wait_event_timeout(i2c->wait, + nouveau_i2c_try_acquire_pad(port) == 0, + timeout) == 0) + return -EBUSY; + } else { + wait_event(i2c->wait, nouveau_i2c_try_acquire_pad(port) == 0); + } + + return 0; +} + +static void +nouveau_i2c_release(struct nouveau_i2c_port *port) +__releases(pad->mutex) +{ + nouveau_i2c(port)->release_pad(port); + mutex_unlock(&port->mutex); +} + +static int +nouveau_i2c_acquire(struct nouveau_i2c_port *port, unsigned long timeout) +__acquires(pad->mutex) +{ + int ret; + mutex_lock(&port->mutex); + if ((ret = nouveau_i2c(port)->acquire_pad(port, timeout))) + mutex_unlock(&port->mutex); + return ret; +} + static int nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, struct nouveau_i2c_board_info *info, @@ -237,11 +325,59 @@ nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, return -ENODEV; } +static void +nouveau_i2c_intr_disable(struct nouveau_event *event, int type, int index) +{ + struct nouveau_i2c *i2c = nouveau_i2c(event->priv); + struct nouveau_i2c_port *port = i2c->find(i2c, index); + const struct nouveau_i2c_impl *impl = (void *)nv_object(i2c)->oclass; + if (port && port->aux >= 0) + impl->aux_mask(i2c, type, 1 << port->aux, 0); +} + +static void +nouveau_i2c_intr_enable(struct nouveau_event *event, int type, int index) +{ + struct nouveau_i2c *i2c = nouveau_i2c(event->priv); + struct nouveau_i2c_port *port = i2c->find(i2c, index); + const struct nouveau_i2c_impl *impl = (void *)nv_object(i2c)->oclass; + if (port && port->aux >= 0) + impl->aux_mask(i2c, type, 1 << port->aux, 1 << port->aux); +} + +static void +nouveau_i2c_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_i2c_impl *impl = (void *)nv_oclass(subdev); + struct nouveau_i2c *i2c = nouveau_i2c(subdev); + struct nouveau_i2c_port *port; + u32 hi, lo, rq, tx, e; + + if (impl->aux_stat) { + impl->aux_stat(i2c, &hi, &lo, &rq, &tx); + if (hi || lo || rq || tx) { + list_for_each_entry(port, &i2c->ports, head) { + if (e = 0, port->aux < 0) + continue; + + if (hi & (1 << port->aux)) e |= NVKM_I2C_PLUG; + if (lo & (1 << port->aux)) e |= NVKM_I2C_UNPLUG; + if (rq & (1 << port->aux)) e |= NVKM_I2C_IRQ; + if (tx & (1 << port->aux)) e |= NVKM_I2C_DONE; + + nouveau_event_trigger(i2c->ntfy, e, port->index); + } + } + } +} + int _nouveau_i2c_fini(struct nouveau_object *object, bool suspend) { + struct nouveau_i2c_impl *impl = (void *)nv_oclass(object); struct nouveau_i2c *i2c = (void *)object; struct nouveau_i2c_port *port; + u32 mask; int ret; list_for_each_entry(port, &i2c->ports, head) { @@ -250,6 +386,11 @@ _nouveau_i2c_fini(struct nouveau_object *object, bool suspend) goto fail; } + if ((mask = (1 << impl->aux) - 1), impl->aux_stat) { + impl->aux_mask(i2c, NVKM_I2C_ANY, mask, 0); + impl->aux_stat(i2c, &mask, &mask, &mask, &mask); + } + return nouveau_subdev_fini(&i2c->base, suspend); fail: list_for_each_entry_continue_reverse(port, &i2c->ports, head) { @@ -290,6 +431,8 @@ _nouveau_i2c_dtor(struct nouveau_object *object) struct nouveau_i2c *i2c = (void *)object; struct nouveau_i2c_port *port, *temp; + nouveau_event_destroy(&i2c->ntfy); + list_for_each_entry_safe(port, temp, &i2c->ports, head) { nouveau_object_ref(NULL, (struct nouveau_object **)&port); } @@ -306,14 +449,14 @@ int nouveau_i2c_create_(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, - struct nouveau_oclass *sclass, int length, void **pobject) { + const struct nouveau_i2c_impl *impl = (void *)oclass; struct nouveau_bios *bios = nouveau_bios(parent); struct nouveau_i2c *i2c; struct nouveau_object *object; struct dcb_i2c_entry info; - int ret, i, j, index = -1; + int ret, i, j, index = -1, pad; struct dcb_output outp; u8 ver, hdr; u32 data; @@ -324,24 +467,48 @@ nouveau_i2c_create_(struct nouveau_object *parent, if (ret) return ret; + nv_subdev(i2c)->intr = nouveau_i2c_intr; i2c->find = nouveau_i2c_find; i2c->find_type = nouveau_i2c_find_type; + i2c->acquire_pad = nouveau_i2c_acquire_pad; + i2c->release_pad = nouveau_i2c_release_pad; + i2c->acquire = nouveau_i2c_acquire; + i2c->release = nouveau_i2c_release; i2c->identify = nouveau_i2c_identify; + init_waitqueue_head(&i2c->wait); INIT_LIST_HEAD(&i2c->ports); while (!dcb_i2c_parse(bios, ++index, &info)) { if (info.type == DCB_I2C_UNUSED) continue; - oclass = sclass; + if (info.share != DCB_I2C_UNUSED) { + if (info.type == DCB_I2C_NVIO_AUX) + pad = info.drive; + else + pad = info.share; + oclass = impl->pad_s; + } else { + pad = 0x100 + info.drive; + oclass = impl->pad_x; + } + + ret = nouveau_object_ctor(NULL, *pobject, oclass, + NULL, pad, &parent); + if (ret < 0) + continue; + + oclass = impl->sclass; do { ret = -EINVAL; if (oclass->handle == info.type) { - ret = nouveau_object_ctor(*pobject, *pobject, + ret = nouveau_object_ctor(parent, *pobject, oclass, &info, index, &object); } } while (ret && (++oclass)->handle); + + nouveau_object_ref(NULL, &parent); } /* in addition to the busses specified in the i2c table, there @@ -380,5 +547,28 @@ nouveau_i2c_create_(struct nouveau_object *parent, } } + ret = nouveau_event_create(4, index, &i2c->ntfy); + if (ret) + return ret; + + i2c->ntfy->priv = i2c; + i2c->ntfy->enable = nouveau_i2c_intr_enable; + i2c->ntfy->disable = nouveau_i2c_intr_disable; + return 0; +} + +int +_nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_i2c *i2c; + int ret; + + ret = nouveau_i2c_create(parent, engine, oclass, &i2c); + *pobject = nv_object(i2c); + if (ret) + return ret; + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c index a6e72d3b06b..813ffc96e86 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/bit.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "subdev/i2c.h" +#include "priv.h" #ifdef CONFIG_NOUVEAU_I2C_INTERNAL #define T_TIMEOUT 2200000 @@ -187,8 +187,9 @@ i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) struct i2c_msg *msg = msgs; int ret = 0, mcnt = num; - if (port->func->acquire) - port->func->acquire(port); + ret = nouveau_i2c(port)->acquire(port, nsecs_to_jiffies(T_TIMEOUT)); + if (ret) + return ret; while (!ret && mcnt--) { u8 remaining = msg->len; @@ -210,6 +211,7 @@ i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) } i2c_stop(port); + nouveau_i2c(port)->release(port); return (ret < 0) ? ret : num; } #else diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c new file mode 100644 index 00000000000..fa891c39866 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/gf117.c @@ -0,0 +1,39 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nv50.h" + +struct nouveau_oclass * +gf117_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0xd7), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, + .dtor = _nouveau_i2c_dtor, + .init = _nouveau_i2c_init, + .fini = _nouveau_i2c_fini, + }, + .sclass = nvd0_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, + .pad_s = &nv04_i2c_pad_oclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c index 860d5d2365d..b1725bdea96 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c @@ -22,9 +22,10 @@ * Authors: Ben Skeggs */ -#include <subdev/i2c.h> #include <subdev/vga.h> +#include "priv.h" + struct nv04_i2c_priv { struct nouveau_i2c base; }; @@ -115,29 +116,15 @@ nv04_i2c_sclass[] = { {} }; -static int -nv04_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv04_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv04_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv04_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x04), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_i2c_ctor, +struct nouveau_oclass * +nv04_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0x04), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, .dtor = _nouveau_i2c_dtor, .init = _nouveau_i2c_init, .fini = _nouveau_i2c_fini, }, -}; + .sclass = nv04_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c index 0c2655a03bb..f16c87ce5ba 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c @@ -22,9 +22,10 @@ * Authors: Ben Skeggs */ -#include <subdev/i2c.h> #include <subdev/vga.h> +#include "priv.h" + struct nv4e_i2c_priv { struct nouveau_i2c base; }; @@ -107,29 +108,15 @@ nv4e_i2c_sclass[] = { {} }; -static int -nv4e_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv4e_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv4e_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv4e_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x4e), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv4e_i2c_ctor, +struct nouveau_oclass * +nv4e_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0x4e), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, .dtor = _nouveau_i2c_dtor, .init = _nouveau_i2c_init, .fini = _nouveau_i2c_fini, }, -}; + .sclass = nv4e_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c index a8d67a28770..7b8756d4df0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c @@ -121,29 +121,15 @@ nv50_i2c_sclass[] = { {} }; -static int -nv50_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv50_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv50_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_i2c_ctor, +struct nouveau_oclass * +nv50_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0x50), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, .dtor = _nouveau_i2c_dtor, .init = _nouveau_i2c_init, .fini = _nouveau_i2c_fini, }, -}; + .sclass = nv50_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h index 4e5ba48ebf5..5d2a77421c7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h @@ -1,7 +1,7 @@ #ifndef __NV50_I2C_H__ #define __NV50_I2C_H__ -#include <subdev/i2c.h> +#include "priv.h" struct nv50_i2c_priv { struct nouveau_i2c base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c index df6d3e4b68b..f59c3a25546 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c @@ -24,6 +24,36 @@ #include "nv50.h" +void +nv94_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx) +{ + u32 intr = nv_rd32(i2c, 0x00e06c); + u32 stat = nv_rd32(i2c, 0x00e068) & intr, i; + for (i = 0, *hi = *lo = *rq = *tx = 0; i < 8; i++) { + if ((stat & (1 << (i * 4)))) *hi |= 1 << i; + if ((stat & (2 << (i * 4)))) *lo |= 1 << i; + if ((stat & (4 << (i * 4)))) *rq |= 1 << i; + if ((stat & (8 << (i * 4)))) *tx |= 1 << i; + } + nv_wr32(i2c, 0x00e06c, intr); +} + +void +nv94_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data) +{ + u32 temp = nv_rd32(i2c, 0x00e068), i; + for (i = 0; i < 8; i++) { + if (mask & (1 << i)) { + if (!(data & (1 << i))) { + temp &= ~(type << (i * 4)); + continue; + } + temp |= type << (i * 4); + } + } + nv_wr32(i2c, 0x00e068, temp); +} + #define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args) #define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args) @@ -69,7 +99,8 @@ auxch_init(struct nouveau_i2c *aux, int ch) } int -nv94_aux(struct nouveau_i2c_port *base, u8 type, u32 addr, u8 *data, u8 size) +nv94_aux(struct nouveau_i2c_port *base, bool retry, + u8 type, u32 addr, u8 *data, u8 size) { struct nouveau_i2c *aux = nouveau_i2c(base); struct nv50_i2c_port *port = (void *)base; @@ -105,9 +136,8 @@ nv94_aux(struct nouveau_i2c_port *base, u8 type, u32 addr, u8 *data, u8 size) ctrl |= size - 1; nv_wr32(aux, 0x00e4e0 + (ch * 0x50), addr); - /* retry transaction a number of times on failure... */ - ret = -EREMOTEIO; - for (retries = 0; retries < 32; retries++) { + /* (maybe) retry transaction a number of times on failure... */ + for (retries = 0; !ret && retries < 32; retries++) { /* reset, and delay a while if this is a retry */ nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl); nv_wr32(aux, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl); @@ -123,16 +153,21 @@ nv94_aux(struct nouveau_i2c_port *base, u8 type, u32 addr, u8 *data, u8 size) udelay(1); if (!timeout--) { AUX_ERR("tx req timeout 0x%08x\n", ctrl); + ret = -EIO; goto out; } } while (ctrl & 0x00010000); + ret = 1; /* read status, and check if transaction completed ok */ stat = nv_mask(aux, 0x00e4e8 + (ch * 0x50), 0, 0); - if (!(stat & 0x000f0f00)) { - ret = 0; - break; - } + if ((stat & 0x000f0000) == 0x00080000 || + (stat & 0x000f0000) == 0x00020000) + ret = retry ? 0 : 1; + if ((stat & 0x00000100)) + ret = -ETIMEDOUT; + if ((stat & 0x00000e00)) + ret = -EIO; AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat); } @@ -147,29 +182,11 @@ nv94_aux(struct nouveau_i2c_port *base, u8 type, u32 addr, u8 *data, u8 size) out: auxch_fini(aux, ch); - return ret; -} - -void -nv94_i2c_acquire(struct nouveau_i2c_port *base) -{ - struct nv50_i2c_priv *priv = (void *)nv_object(base)->engine; - struct nv50_i2c_port *port = (void *)base; - if (port->ctrl) { - nv_mask(priv, port->ctrl + 0x0c, 0x00000001, 0x00000000); - nv_mask(priv, port->ctrl + 0x00, 0x0000f003, port->data); - } -} - -void -nv94_i2c_release(struct nouveau_i2c_port *base) -{ + return ret < 0 ? ret : (stat & 0x000f0000) >> 16; } static const struct nouveau_i2c_func nv94_i2c_func = { - .acquire = nv94_i2c_acquire, - .release = nv94_i2c_release, .drive_scl = nv50_i2c_drive_scl, .drive_sda = nv50_i2c_drive_sda, .sense_scl = nv50_i2c_sense_scl, @@ -206,8 +223,6 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, static const struct nouveau_i2c_func nv94_aux_func = { - .acquire = nv94_i2c_acquire, - .release = nv94_i2c_release, .aux = nv94_aux, }; @@ -227,6 +242,7 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; + port->base.aux = info->drive; port->addr = info->drive; if (info->share != DCB_I2C_UNUSED) { port->ctrl = 0x00e500 + (info->drive * 0x50); @@ -257,29 +273,19 @@ nv94_i2c_sclass[] = { {} }; -static int -nv94_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nv94_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv94_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0x94), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv94_i2c_ctor, +struct nouveau_oclass * +nv94_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0x94), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, .dtor = _nouveau_i2c_dtor, .init = _nouveau_i2c_init, .fini = _nouveau_i2c_fini, }, -}; + .sclass = nv94_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, + .pad_s = &nv94_i2c_pad_oclass, + .aux = 4, + .aux_stat = nv94_aux_stat, + .aux_mask = nv94_aux_mask, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c index 29967d30f97..364ddb1c5f0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c @@ -42,8 +42,6 @@ nvd0_i2c_sense_sda(struct nouveau_i2c_port *base) static const struct nouveau_i2c_func nvd0_i2c_func = { - .acquire = nv94_i2c_acquire, - .release = nv94_i2c_release, .drive_scl = nv50_i2c_drive_scl, .drive_sda = nv50_i2c_drive_sda, .sense_scl = nvd0_i2c_sense_scl, @@ -75,7 +73,7 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -static struct nouveau_oclass +struct nouveau_oclass nvd0_i2c_sclass[] = { { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT), .ofuncs = &(struct nouveau_ofuncs) { @@ -96,29 +94,19 @@ nvd0_i2c_sclass[] = { {} }; -static int -nvd0_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv50_i2c_priv *priv; - int ret; - - ret = nouveau_i2c_create(parent, engine, oclass, nvd0_i2c_sclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nvd0_i2c_oclass = { - .handle = NV_SUBDEV(I2C, 0xd0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_i2c_ctor, +struct nouveau_oclass * +nvd0_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0xd0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, .dtor = _nouveau_i2c_dtor, .init = _nouveau_i2c_init, .fini = _nouveau_i2c_fini, }, -}; + .sclass = nvd0_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, + .pad_s = &nv94_i2c_pad_oclass, + .aux = 4, + .aux_stat = nv94_aux_stat, + .aux_mask = nv94_aux_mask, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c new file mode 100644 index 00000000000..cae77e1ad8d --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c @@ -0,0 +1,72 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nv50.h" + +static void +nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx) +{ + u32 intr = nv_rd32(i2c, 0x00dc60); + u32 stat = nv_rd32(i2c, 0x00dc68) & intr, i; + for (i = 0, *hi = *lo = *rq = *tx = 0; i < 8; i++) { + if ((stat & (1 << (i * 4)))) *hi |= 1 << i; + if ((stat & (2 << (i * 4)))) *lo |= 1 << i; + if ((stat & (4 << (i * 4)))) *rq |= 1 << i; + if ((stat & (8 << (i * 4)))) *tx |= 1 << i; + } + nv_wr32(i2c, 0x00dc60, intr); +} + +static void +nve0_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data) +{ + u32 temp = nv_rd32(i2c, 0x00dc68), i; + for (i = 0; i < 8; i++) { + if (mask & (1 << i)) { + if (!(data & (1 << i))) { + temp &= ~(type << (i * 4)); + continue; + } + temp |= type << (i * 4); + } + } + nv_wr32(i2c, 0x00dc68, temp); +} + +struct nouveau_oclass * +nve0_i2c_oclass = &(struct nouveau_i2c_impl) { + .base.handle = NV_SUBDEV(I2C, 0xe0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nouveau_i2c_ctor, + .dtor = _nouveau_i2c_dtor, + .init = _nouveau_i2c_init, + .fini = _nouveau_i2c_fini, + }, + .sclass = nvd0_i2c_sclass, + .pad_x = &nv04_i2c_pad_oclass, + .pad_s = &nv94_i2c_pad_oclass, + .aux = 4, + .aux_stat = nve0_aux_stat, + .aux_mask = nve0_aux_mask, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.c new file mode 100644 index 00000000000..e9e412477c1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.c @@ -0,0 +1,84 @@ +/* + * 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 "pad.h" + +int +_nvkm_i2c_pad_fini(struct nouveau_object *object, bool suspend) +{ + struct nvkm_i2c_pad *pad = (void *)object; + DBG("-> NULL\n"); + pad->port = NULL; + return nouveau_object_fini(&pad->base, suspend); +} + +int +_nvkm_i2c_pad_init(struct nouveau_object *object) +{ + struct nvkm_i2c_pad *pad = (void *)object; + DBG("-> PORT:%02x\n", pad->next->index); + pad->port = pad->next; + return nouveau_object_init(&pad->base); +} + +int +nvkm_i2c_pad_create_(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, int index, + int size, void **pobject) +{ + struct nouveau_i2c *i2c = (void *)engine; + struct nouveau_i2c_port *port; + struct nvkm_i2c_pad *pad; + int ret; + + list_for_each_entry(port, &i2c->ports, head) { + pad = nvkm_i2c_pad(port); + if (pad->index == index) { + atomic_inc(&nv_object(pad)->refcount); + *pobject = pad; + return 1; + } + } + + ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject); + pad = *pobject; + if (ret) + return ret; + + pad->index = index; + return 0; +} + +int +_nvkm_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 index, + struct nouveau_object **pobject) +{ + struct nvkm_i2c_pad *pad; + int ret; + ret = nvkm_i2c_pad_create(parent, engine, oclass, index, &pad); + *pobject = nv_object(pad); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.h new file mode 100644 index 00000000000..452ac10c300 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/pad.h @@ -0,0 +1,58 @@ +#ifndef __NVKM_I2C_PAD_H__ +#define __NVKM_I2C_PAD_H__ + +#include "priv.h" + +struct nvkm_i2c_pad { + struct nouveau_object base; + int index; + struct nouveau_i2c_port *port; + struct nouveau_i2c_port *next; +}; + +static inline struct nvkm_i2c_pad * +nvkm_i2c_pad(struct nouveau_i2c_port *port) +{ + struct nouveau_object *pad = nv_object(port); + while (pad->parent) + pad = pad->parent; + return (void *)pad; +} + +#define nvkm_i2c_pad_create(p,e,o,i,d) \ + nvkm_i2c_pad_create_((p), (e), (o), (i), sizeof(**d), (void **)d) +#define nvkm_i2c_pad_destroy(p) ({ \ + struct nvkm_i2c_pad *_p = (p); \ + _nvkm_i2c_pad_dtor(nv_object(_p)); \ +}) +#define nvkm_i2c_pad_init(p) ({ \ + struct nvkm_i2c_pad *_p = (p); \ + _nvkm_i2c_pad_init(nv_object(_p)); \ +}) +#define nvkm_i2c_pad_fini(p,s) ({ \ + struct nvkm_i2c_pad *_p = (p); \ + _nvkm_i2c_pad_fini(nv_object(_p), (s)); \ +}) + +int nvkm_i2c_pad_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int index, int, void **); + +int _nvkm_i2c_pad_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +#define _nvkm_i2c_pad_dtor nouveau_object_destroy +int _nvkm_i2c_pad_init(struct nouveau_object *); +int _nvkm_i2c_pad_fini(struct nouveau_object *, bool); + +#ifndef MSG +#define MSG(l,f,a...) do { \ + struct nvkm_i2c_pad *_pad = (void *)pad; \ + nv_##l(nv_object(_pad)->engine, "PAD:%c:%02x: "f, \ + _pad->index >= 0x100 ? 'X' : 'S', \ + _pad->index >= 0x100 ? _pad->index - 0x100 : _pad->index, ##a); \ +} while(0) +#define DBG(f,a...) MSG(debug, f, ##a) +#define ERR(f,a...) MSG(error, f, ##a) +#endif + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv04.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv04.c new file mode 100644 index 00000000000..2c4b61296dd --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv04.c @@ -0,0 +1,35 @@ +/* + * 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 "pad.h" + +struct nouveau_oclass +nv04_i2c_pad_oclass = { + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = _nvkm_i2c_pad_ctor, + .dtor = _nvkm_i2c_pad_dtor, + .init = _nvkm_i2c_pad_init, + .fini = _nvkm_i2c_pad_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv94.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv94.c new file mode 100644 index 00000000000..0dc6753014f --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/padnv94.c @@ -0,0 +1,86 @@ +/* + * 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 "pad.h" + +struct nv94_i2c_pad { + struct nvkm_i2c_pad base; + int addr; +}; + +static int +nv94_i2c_pad_fini(struct nouveau_object *object, bool suspend) +{ + struct nouveau_i2c *i2c = (void *)object->engine; + struct nv94_i2c_pad *pad = (void *)object; + nv_mask(i2c, 0x00e50c + pad->addr, 0x00000001, 0x00000001); + return nvkm_i2c_pad_fini(&pad->base, suspend); +} + +static int +nv94_i2c_pad_init(struct nouveau_object *object) +{ + struct nouveau_i2c *i2c = (void *)object->engine; + struct nv94_i2c_pad *pad = (void *)object; + + switch (nv_oclass(pad->base.next)->handle) { + case NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX): + nv_mask(i2c, 0x00e500 + pad->addr, 0x0000c003, 0x00000002); + break; + case NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT): + default: + nv_mask(i2c, 0x00e500 + pad->addr, 0x0000c003, 0x0000c001); + break; + } + + nv_mask(i2c, 0x00e50c + pad->addr, 0x00000001, 0x00000000); + return nvkm_i2c_pad_init(&pad->base); +} + +static int +nv94_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 index, + struct nouveau_object **pobject) +{ + struct nv94_i2c_pad *pad; + int ret; + + ret = nvkm_i2c_pad_create(parent, engine, oclass, index, &pad); + *pobject = nv_object(pad); + if (ret) + return ret; + + pad->addr = index * 0x50;; + return 0; +} + +struct nouveau_oclass +nv94_i2c_pad_oclass = { + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv94_i2c_pad_ctor, + .dtor = _nvkm_i2c_pad_dtor, + .init = nv94_i2c_pad_init, + .fini = nv94_i2c_pad_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/port.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/port.h new file mode 100644 index 00000000000..a8ff6e077af --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/port.h @@ -0,0 +1,15 @@ +#ifndef __NVKM_I2C_PORT_H__ +#define __NVKM_I2C_PORT_H__ + +#include "priv.h" + +#ifndef MSG +#define MSG(l,f,a...) do { \ + struct nouveau_i2c_port *_port = (void *)port; \ + nv_##l(nv_object(_port)->engine, "PORT:%02x: "f, _port->index, ##a); \ +} while(0) +#define DBG(f,a...) MSG(debug, f, ##a) +#define ERR(f,a...) MSG(error, f, ##a) +#endif + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h new file mode 100644 index 00000000000..780090b6425 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h @@ -0,0 +1,85 @@ +#ifndef __NVKM_I2C_H__ +#define __NVKM_I2C_H__ + +#include <subdev/i2c.h> + +extern struct nouveau_oclass nv04_i2c_pad_oclass; +extern struct nouveau_oclass nv94_i2c_pad_oclass; + +#define nouveau_i2c_port_create(p,e,o,i,a,f,d) \ + nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \ + sizeof(**d), (void **)d) +#define nouveau_i2c_port_destroy(p) ({ \ + struct nouveau_i2c_port *port = (p); \ + _nouveau_i2c_port_dtor(nv_object(i2c)); \ +}) +#define nouveau_i2c_port_init(p) \ + nouveau_object_init(&(p)->base) +#define nouveau_i2c_port_fini(p,s) \ + nouveau_object_fini(&(p)->base, (s)) + +int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, u8, + const struct i2c_algorithm *, + const struct nouveau_i2c_func *, + int, void **); +void _nouveau_i2c_port_dtor(struct nouveau_object *); +#define _nouveau_i2c_port_init nouveau_object_init +int _nouveau_i2c_port_fini(struct nouveau_object *, bool); + +#define nouveau_i2c_create(p,e,o,d) \ + nouveau_i2c_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_i2c_destroy(p) ({ \ + struct nouveau_i2c *i2c = (p); \ + _nouveau_i2c_dtor(nv_object(i2c)); \ +}) +#define nouveau_i2c_init(p) ({ \ + struct nouveau_i2c *i2c = (p); \ + _nouveau_i2c_init(nv_object(i2c)); \ +}) +#define nouveau_i2c_fini(p,s) ({ \ + struct nouveau_i2c *i2c = (p); \ + _nouveau_i2c_fini(nv_object(i2c), (s)); \ +}) + +int nouveau_i2c_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +int _nouveau_i2c_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void _nouveau_i2c_dtor(struct nouveau_object *); +int _nouveau_i2c_init(struct nouveau_object *); +int _nouveau_i2c_fini(struct nouveau_object *, bool); + +extern struct nouveau_oclass nouveau_anx9805_sclass[]; +extern struct nouveau_oclass nvd0_i2c_sclass[]; + +extern const struct i2c_algorithm nouveau_i2c_bit_algo; +extern const struct i2c_algorithm nouveau_i2c_aux_algo; + +struct nouveau_i2c_impl { + struct nouveau_oclass base; + + /* supported i2c port classes */ + struct nouveau_oclass *sclass; + struct nouveau_oclass *pad_x; + struct nouveau_oclass *pad_s; + + /* number of native dp aux channels present */ + int aux; + + /* read and ack pending interrupts, returning only data + * for ports that have not been masked off, while still + * performing the ack for anything that was pending. + */ + void (*aux_stat)(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *); + + /* mask on/off interrupt types for a given set of auxch + */ + void (*aux_mask)(struct nouveau_i2c *, u32, u32, u32); +}; + +void nv94_aux_stat(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *); +void nv94_aux_mask(struct nouveau_i2c *, u32, u32, u32); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c new file mode 100644 index 00000000000..245f0ebaa6a --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include <subdev/ibus.h> +#include <subdev/timer.h> + +struct gk20a_ibus_priv { + struct nouveau_ibus base; +}; + +static void +gk20a_ibus_init_priv_ring(struct gk20a_ibus_priv *priv) +{ + nv_mask(priv, 0x137250, 0x3f, 0); + + nv_mask(priv, 0x000200, 0x20, 0); + usleep_range(20, 30); + nv_mask(priv, 0x000200, 0x20, 0x20); + + nv_wr32(priv, 0x12004c, 0x4); + nv_wr32(priv, 0x122204, 0x2); + nv_rd32(priv, 0x122204); +} + +static void +gk20a_ibus_intr(struct nouveau_subdev *subdev) +{ + struct gk20a_ibus_priv *priv = (void *)subdev; + u32 status0 = nv_rd32(priv, 0x120058); + + if (status0 & 0x7) { + nv_debug(priv, "resetting priv ring\n"); + gk20a_ibus_init_priv_ring(priv); + } + + /* Acknowledge interrupt */ + nv_mask(priv, 0x12004c, 0x2, 0x2); + + if (!nv_wait(subdev, 0x12004c, 0x3f, 0x00)) + nv_warn(priv, "timeout waiting for ringmaster ack\n"); +} + +static int +gk20a_ibus_init(struct nouveau_object *object) +{ + struct gk20a_ibus_priv *priv = (void *)object; + int ret; + + ret = _nouveau_ibus_init(object); + if (ret) + return ret; + + gk20a_ibus_init_priv_ring(priv); + + return 0; +} + +static int +gk20a_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct gk20a_ibus_priv *priv; + int ret; + + ret = nouveau_ibus_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->intr = gk20a_ibus_intr; + return 0; +} + +struct nouveau_oclass +gk20a_ibus_oclass = { + .handle = NV_SUBDEV(IBUS, 0xea), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = gk20a_ibus_ctor, + .dtor = _nouveau_ibus_dtor, + .init = gk20a_ibus_init, + .fini = _nouveau_ibus_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c index 7120124dcea..ebef970a064 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/nve0.c @@ -95,6 +95,23 @@ nve0_ibus_intr(struct nouveau_subdev *subdev) } static int +nve0_ibus_init(struct nouveau_object *object) +{ + struct nve0_ibus_priv *priv = (void *)object; + int ret = nouveau_ibus_init(&priv->base); + if (ret == 0) { + nv_mask(priv, 0x122318, 0x0003ffff, 0x00001000); + nv_mask(priv, 0x12231c, 0x0003ffff, 0x00000200); + nv_mask(priv, 0x122310, 0x0003ffff, 0x00000800); + nv_mask(priv, 0x122348, 0x0003ffff, 0x00000100); + nv_mask(priv, 0x1223b0, 0x0003ffff, 0x00000fff); + nv_mask(priv, 0x122348, 0x0003ffff, 0x00000200); + nv_mask(priv, 0x122358, 0x0003ffff, 0x00002880); + } + return ret; +} + +static int nve0_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) @@ -117,7 +134,7 @@ nve0_ibus_oclass = { .ofuncs = &(struct nouveau_ofuncs) { .ctor = nve0_ibus_ctor, .dtor = _nouveau_ibus_dtor, - .init = _nouveau_ibus_init, + .init = nve0_ibus_init, .fini = _nouveau_ibus_fini, }, }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c index ec0b9661d61..8803809f9fc 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c @@ -50,7 +50,6 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nouveau_device *device = nv_device(parent); - struct pci_dev *pdev = device->pdev; struct nv04_instmem_priv *priv; int ret, bar, vs; @@ -60,13 +59,13 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; /* map bar */ - if (pci_resource_len(pdev, 2)) + if (nv_device_resource_len(device, 2)) bar = 2; else bar = 3; - priv->iomem = ioremap(pci_resource_start(pdev, bar), - pci_resource_len(pdev, bar)); + priv->iomem = ioremap(nv_device_resource_start(device, bar), + nv_device_resource_len(device, bar)); if (!priv->iomem) { nv_error(priv, "unable to map PRAMIN BAR\n"); return -EFAULT; diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c index cce65cc5651..f2f3338a967 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.c @@ -22,44 +22,35 @@ * Authors: Ben Skeggs */ -#include <subdev/ltcg.h> #include <subdev/fb.h> #include <subdev/timer.h> -struct nvc0_ltcg_priv { - struct nouveau_ltcg base; - u32 part_nr; - u32 subp_nr; - u32 num_tags; - u32 tag_base; - struct nouveau_mm tags; - struct nouveau_mm_node *tag_ram; -}; +#include "gf100.h" static void -nvc0_ltcg_subp_isr(struct nvc0_ltcg_priv *priv, int unit, int subp) +gf100_ltcg_lts_isr(struct gf100_ltcg_priv *priv, int ltc, int lts) { - u32 subp_base = 0x141000 + (unit * 0x2000) + (subp * 0x400); - u32 stat = nv_rd32(priv, subp_base + 0x020); + u32 base = 0x141000 + (ltc * 0x2000) + (lts * 0x400); + u32 stat = nv_rd32(priv, base + 0x020); if (stat) { - nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", unit, subp, stat); - nv_wr32(priv, subp_base + 0x020, stat); + nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", ltc, lts, stat); + nv_wr32(priv, base + 0x020, stat); } } static void -nvc0_ltcg_intr(struct nouveau_subdev *subdev) +gf100_ltcg_intr(struct nouveau_subdev *subdev) { - struct nvc0_ltcg_priv *priv = (void *)subdev; - u32 units; - - units = nv_rd32(priv, 0x00017c); - while (units) { - u32 subp, unit = ffs(units) - 1; - for (subp = 0; subp < priv->subp_nr; subp++) - nvc0_ltcg_subp_isr(priv, unit, subp); - units &= ~(1 << unit); + struct gf100_ltcg_priv *priv = (void *)subdev; + u32 mask; + + mask = nv_rd32(priv, 0x00017c); + while (mask) { + u32 lts, ltc = __ffs(mask); + for (lts = 0; lts < priv->lts_nr; lts++) + gf100_ltcg_lts_isr(priv, ltc, lts); + mask &= ~(1 << ltc); } /* we do something horribly wrong and upset PMFB a lot, so mask off @@ -68,11 +59,11 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev) nv_mask(priv, 0x000640, 0x02000000, 0x00000000); } -static int -nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, +int +gf100_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, struct nouveau_mm_node **pnode) { - struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; int ret; ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode); @@ -82,18 +73,18 @@ nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n, return ret; } -static void -nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) +void +gf100_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode) { - struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; nouveau_mm_free(&priv->tags, pnode); } static void -nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) +gf100_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) { - struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; u32 last = first + count - 1; int p, i; @@ -104,16 +95,16 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */ /* wait until it's finished with clearing */ - for (p = 0; p < priv->part_nr; ++p) { - for (i = 0; i < priv->subp_nr; ++i) + for (p = 0; p < priv->ltc_nr; ++p) { + for (i = 0; i < priv->lts_nr; ++i) nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0); } } /* TODO: Figure out tag memory details and drop the over-cautious allocation. */ -static int -nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) +int +gf100_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct gf100_ltcg_priv *priv) { u32 tag_size, tag_margin, tag_align; int ret; @@ -124,7 +115,7 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) priv->num_tags = 1 << 17; /* we have 17 bits in PTE */ priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */ - tag_align = priv->part_nr * 0x800; + tag_align = priv->ltc_nr * 0x800; tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align; /* 4 part 4 sub: 0x2000 bytes for 56 tags */ @@ -157,11 +148,11 @@ nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv) } static int -nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, +gf100_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nvc0_ltcg_priv *priv; + struct gf100_ltcg_priv *priv; struct nouveau_fb *pfb = nouveau_fb(parent); u32 parts, mask; int ret, i; @@ -175,27 +166,27 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, mask = nv_rd32(priv, 0x022554); for (i = 0; i < parts; i++) { if (!(mask & (1 << i))) - priv->part_nr++; + priv->ltc_nr++; } - priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28; + priv->lts_nr = nv_rd32(priv, 0x17e8dc) >> 28; - ret = nvc0_ltcg_init_tag_ram(pfb, priv); + ret = gf100_ltcg_init_tag_ram(pfb, priv); if (ret) return ret; - priv->base.tags_alloc = nvc0_ltcg_tags_alloc; - priv->base.tags_free = nvc0_ltcg_tags_free; - priv->base.tags_clear = nvc0_ltcg_tags_clear; + priv->base.tags_alloc = gf100_ltcg_tags_alloc; + priv->base.tags_free = gf100_ltcg_tags_free; + priv->base.tags_clear = gf100_ltcg_tags_clear; - nv_subdev(priv)->intr = nvc0_ltcg_intr; + nv_subdev(priv)->intr = gf100_ltcg_intr; return 0; } -static void -nvc0_ltcg_dtor(struct nouveau_object *object) +void +gf100_ltcg_dtor(struct nouveau_object *object) { struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; - struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent); nouveau_mm_fini(&priv->tags); @@ -205,10 +196,10 @@ nvc0_ltcg_dtor(struct nouveau_object *object) } static int -nvc0_ltcg_init(struct nouveau_object *object) +gf100_ltcg_init(struct nouveau_object *object) { struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; - struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg; + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; int ret; ret = nouveau_ltcg_init(ltcg); @@ -216,20 +207,20 @@ nvc0_ltcg_init(struct nouveau_object *object) return ret; nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ - nv_wr32(priv, 0x17e8d8, priv->part_nr); + nv_wr32(priv, 0x17e8d8, priv->ltc_nr); if (nv_device(ltcg)->card_type >= NV_E0) - nv_wr32(priv, 0x17e000, priv->part_nr); + nv_wr32(priv, 0x17e000, priv->ltc_nr); nv_wr32(priv, 0x17e8d4, priv->tag_base); return 0; } -struct nouveau_oclass -nvc0_ltcg_oclass = { +struct nouveau_oclass * +gf100_ltcg_oclass = &(struct nouveau_oclass) { .handle = NV_SUBDEV(LTCG, 0xc0), .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_ltcg_ctor, - .dtor = nvc0_ltcg_dtor, - .init = nvc0_ltcg_init, + .ctor = gf100_ltcg_ctor, + .dtor = gf100_ltcg_dtor, + .init = gf100_ltcg_init, .fini = _nouveau_ltcg_fini, }, }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h new file mode 100644 index 00000000000..87b10b8412e --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gf100.h @@ -0,0 +1,21 @@ +#ifndef __NVKM_LTCG_PRIV_GF100_H__ +#define __NVKM_LTCG_PRIV_GF100_H__ + +#include <subdev/ltcg.h> + +struct gf100_ltcg_priv { + struct nouveau_ltcg base; + u32 ltc_nr; + u32 lts_nr; + u32 num_tags; + u32 tag_base; + struct nouveau_mm tags; + struct nouveau_mm_node *tag_ram; +}; + +void gf100_ltcg_dtor(struct nouveau_object *); +int gf100_ltcg_init_tag_ram(struct nouveau_fb *, struct gf100_ltcg_priv *); +int gf100_ltcg_tags_alloc(struct nouveau_ltcg *, u32, struct nouveau_mm_node **); +void gf100_ltcg_tags_free(struct nouveau_ltcg *, struct nouveau_mm_node **); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c new file mode 100644 index 00000000000..e79d0e81de4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/gm107.c @@ -0,0 +1,142 @@ +/* + * 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 <subdev/fb.h> +#include <subdev/timer.h> + +#include "gf100.h" + +static void +gm107_ltcg_lts_isr(struct gf100_ltcg_priv *priv, int ltc, int lts) +{ + u32 base = 0x140000 + (ltc * 0x2000) + (lts * 0x400); + u32 stat = nv_rd32(priv, base + 0x00c); + + if (stat) { + nv_info(priv, "LTC%d_LTS%d: 0x%08x\n", ltc, lts, stat); + nv_wr32(priv, base + 0x00c, stat); + } +} + +static void +gm107_ltcg_intr(struct nouveau_subdev *subdev) +{ + struct gf100_ltcg_priv *priv = (void *)subdev; + u32 mask; + + mask = nv_rd32(priv, 0x00017c); + while (mask) { + u32 lts, ltc = __ffs(mask); + for (lts = 0; lts < priv->lts_nr; lts++) + gm107_ltcg_lts_isr(priv, ltc, lts); + mask &= ~(1 << ltc); + } + + /* we do something horribly wrong and upset PMFB a lot, so mask off + * interrupts from it after the first one until it's fixed + */ + nv_mask(priv, 0x000640, 0x02000000, 0x00000000); +} + +static void +gm107_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) +{ + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; + u32 last = first + count - 1; + int p, i; + + BUG_ON((first > last) || (last >= priv->num_tags)); + + nv_wr32(priv, 0x17e270, first); + nv_wr32(priv, 0x17e274, last); + nv_wr32(priv, 0x17e26c, 0x4); /* trigger clear */ + + /* wait until it's finished with clearing */ + for (p = 0; p < priv->ltc_nr; ++p) { + for (i = 0; i < priv->lts_nr; ++i) + nv_wait(priv, 0x14046c + p * 0x2000 + i * 0x200, ~0, 0); + } +} + +static int +gm107_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct gf100_ltcg_priv *priv; + struct nouveau_fb *pfb = nouveau_fb(parent); + u32 parts, mask; + int ret, i; + + ret = nouveau_ltcg_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + parts = nv_rd32(priv, 0x022438); + mask = nv_rd32(priv, 0x021c14); + for (i = 0; i < parts; i++) { + if (!(mask & (1 << i))) + priv->ltc_nr++; + } + priv->lts_nr = nv_rd32(priv, 0x17e280) >> 28; + + ret = gf100_ltcg_init_tag_ram(pfb, priv); + if (ret) + return ret; + + priv->base.tags_alloc = gf100_ltcg_tags_alloc; + priv->base.tags_free = gf100_ltcg_tags_free; + priv->base.tags_clear = gm107_ltcg_tags_clear; + + nv_subdev(priv)->intr = gm107_ltcg_intr; + return 0; +} + +static int +gm107_ltcg_init(struct nouveau_object *object) +{ + struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object; + struct gf100_ltcg_priv *priv = (struct gf100_ltcg_priv *)ltcg; + int ret; + + ret = nouveau_ltcg_init(ltcg); + if (ret) + return ret; + + nv_wr32(priv, 0x17e27c, priv->ltc_nr); + nv_wr32(priv, 0x17e278, priv->tag_base); + return 0; +} + +struct nouveau_oclass * +gm107_ltcg_oclass = &(struct nouveau_oclass) { + .handle = NV_SUBDEV(LTCG, 0xff), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = gm107_ltcg_ctor, + .dtor = gf100_ltcg_dtor, + .init = gm107_ltcg_init, + .fini = _nouveau_ltcg_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c index b4b9943773b..8a5555192fa 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c @@ -93,7 +93,7 @@ _nouveau_mc_dtor(struct nouveau_object *object) { struct nouveau_device *device = nv_device(object); struct nouveau_mc *pmc = (void *)object; - free_irq(device->pdev->irq, pmc); + free_irq(pmc->irq, pmc); if (pmc->use_msi) pci_disable_msi(device->pdev); nouveau_subdev_destroy(&pmc->base); @@ -114,33 +114,44 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - switch (device->pdev->device & 0x0ff0) { - case 0x00f0: - case 0x02e0: - /* BR02? NFI how these would be handled yet exactly */ - break; - default: - switch (device->chipset) { - case 0xaa: break; /* reported broken, nv also disable it */ - default: - pmc->use_msi = true; + if (nv_device_is_pci(device)) + switch (device->pdev->device & 0x0ff0) { + case 0x00f0: + case 0x02e0: + /* BR02? NFI how these would be handled yet exactly */ break; + default: + switch (device->chipset) { + case 0xaa: + /* reported broken, nv also disable it */ + break; + default: + pmc->use_msi = true; + break; } - } - pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", pmc->use_msi); - if (pmc->use_msi && oclass->msi_rearm) { - pmc->use_msi = pci_enable_msi(device->pdev) == 0; - if (pmc->use_msi) { - nv_info(pmc, "MSI interrupts enabled\n"); - oclass->msi_rearm(pmc); + pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", + pmc->use_msi); + + if (pmc->use_msi && oclass->msi_rearm) { + pmc->use_msi = pci_enable_msi(device->pdev) == 0; + if (pmc->use_msi) { + nv_info(pmc, "MSI interrupts enabled\n"); + oclass->msi_rearm(pmc); + } + } else { + pmc->use_msi = false; } - } else { - pmc->use_msi = false; } - ret = request_irq(device->pdev->irq, nouveau_mc_intr, - IRQF_SHARED, "nouveau", pmc); + ret = nv_device_get_irq(device, true); + if (ret < 0) + return ret; + pmc->irq = ret; + + ret = request_irq(pmc->irq, nouveau_mc_intr, IRQF_SHARED, "nouveau", + pmc); + if (ret < 0) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h index b0d5c31606c..81a408e7d03 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h @@ -14,6 +14,7 @@ int nv04_mc_ctor(struct nouveau_object *, struct nouveau_object *, extern const struct nouveau_mc_intr nv04_mc_intr[]; int nv04_mc_init(struct nouveau_object *); void nv40_mc_msi_rearm(struct nouveau_mc *); +int nv44_mc_init(struct nouveau_object *object); int nv50_mc_init(struct nouveau_object *); extern const struct nouveau_mc_intr nv50_mc_intr[]; extern const struct nouveau_mc_intr nvc0_mc_intr[]; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c index 3bfee5c6c4f..cc4d0d2d886 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c @@ -24,7 +24,7 @@ #include "nv04.h" -static int +int nv44_mc_init(struct nouveau_object *object) { struct nv04_mc_priv *priv = (void *)object; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c new file mode 100644 index 00000000000..a75c35ccf25 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c @@ -0,0 +1,45 @@ +/* + * Copyright 2014 Ilia Mirkin + * + * 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: Ilia Mirkin + */ + +#include "nv04.h" + +static void +nv4c_mc_msi_rearm(struct nouveau_mc *pmc) +{ + struct nv04_mc_priv *priv = (void *)pmc; + nv_wr08(priv, 0x088050, 0xff); +} + +struct nouveau_oclass * +nv4c_mc_oclass = &(struct nouveau_mc_oclass) { + .base.handle = NV_SUBDEV(MC, 0x4c), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv04_mc_ctor, + .dtor = _nouveau_mc_dtor, + .init = nv44_mc_init, + .fini = _nouveau_mc_fini, + }, + .intr = nv04_mc_intr, + .msi_rearm = nv4c_mc_msi_rearm, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index e8822a934c4..9ca93e2718f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c @@ -26,6 +26,7 @@ const struct nouveau_mc_intr nv50_mc_intr[] = { + { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */ { 0x00000001, NVDEV_ENGINE_MPEG }, { 0x00000100, NVDEV_ENGINE_FIFO }, { 0x00001000, NVDEV_ENGINE_GR }, @@ -33,8 +34,8 @@ nv50_mc_intr[] = { { 0x00008000, NVDEV_ENGINE_BSP }, /* NV84- */ { 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */ { 0x00100000, NVDEV_SUBDEV_TIMER }, - { 0x00200000, NVDEV_SUBDEV_GPIO }, - { 0x04000000, NVDEV_ENGINE_DISP }, + { 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */ + { 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */ { 0x10000000, NVDEV_SUBDEV_BUS }, { 0x80000000, NVDEV_ENGINE_SW }, { 0x0002d101, NVDEV_SUBDEV_FB }, diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c index f8a6f18e2d3..3c76d9038f3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c @@ -26,6 +26,7 @@ static const struct nouveau_mc_intr nv98_mc_intr[] = { + { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */ { 0x00000001, NVDEV_ENGINE_PPP }, { 0x00000100, NVDEV_ENGINE_FIFO }, { 0x00001000, NVDEV_ENGINE_GR }, @@ -35,9 +36,9 @@ nv98_mc_intr[] = { { 0x00040000, NVDEV_SUBDEV_PWR }, /* NVA3:NVC0 */ { 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */ { 0x00100000, NVDEV_SUBDEV_TIMER }, - { 0x00200000, NVDEV_SUBDEV_GPIO }, + { 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */ + { 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */ { 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */ - { 0x04000000, NVDEV_ENGINE_DISP }, { 0x10000000, NVDEV_SUBDEV_BUS }, { 0x80000000, NVDEV_ENGINE_SW }, { 0x0042d101, NVDEV_SUBDEV_FB }, diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c index 34472d31709..f9c6a678b47 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c @@ -26,6 +26,7 @@ const struct nouveau_mc_intr nvc0_mc_intr[] = { + { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */ { 0x00000001, NVDEV_ENGINE_PPP }, { 0x00000020, NVDEV_ENGINE_COPY0 }, { 0x00000040, NVDEV_ENGINE_COPY1 }, @@ -37,10 +38,10 @@ nvc0_mc_intr[] = { { 0x00040000, NVDEV_SUBDEV_THERM }, { 0x00020000, NVDEV_ENGINE_VP }, { 0x00100000, NVDEV_SUBDEV_TIMER }, - { 0x00200000, NVDEV_SUBDEV_GPIO }, + { 0x00200000, NVDEV_SUBDEV_GPIO }, /* PMGR->GPIO */ + { 0x00200000, NVDEV_SUBDEV_I2C }, /* PMGR->I2C/AUX */ { 0x01000000, NVDEV_SUBDEV_PWR }, { 0x02000000, NVDEV_SUBDEV_LTCG }, - { 0x04000000, NVDEV_ENGINE_DISP }, { 0x08000000, NVDEV_SUBDEV_FB }, { 0x10000000, NVDEV_SUBDEV_BUS }, { 0x40000000, NVDEV_SUBDEV_IBUS }, diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c index 13c5af88a60..51fcf796041 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c @@ -96,7 +96,7 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version) acpi_handle handle; int rev; - handle = ACPI_HANDLE(&device->pdev->dev); + handle = ACPI_HANDLE(nv_device_base(device)); if (!handle) return false; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c index 64f8b4702bf..fcaabe8456e 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/nv50.c @@ -150,7 +150,7 @@ mxm_dcb_sanitise_entry(struct nouveau_bios *bios, void *data, int idx, u16 pdcb) * common example is DP->eDP. */ conn = bios->data; - conn += dcb_conn(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len); + conn += nvbios_connEe(bios, (ctx.outp[0] & 0x0000f000) >> 12, &ver, &len); type = conn[0]; switch (ctx.desc.conn_type) { case 0x01: /* LVDS */ diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc index 2284ecb1c9b..c2bb616a8da 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc @@ -83,7 +83,7 @@ host_send: // increment GET add b32 $r1 0x1 and $r14 $r1 #fifo_qmaskf - nv_iowr(NV_PPWR_FIFO_GET(0), $r1) + nv_iowr(NV_PPWR_FIFO_GET(0), $r14) bra #host_send host_send_done: ret diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h index 4bd43a99fdc..39a5dc150a0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h @@ -1018,7 +1018,7 @@ uint32_t nv108_pwr_code[] = { 0xb600023f, 0x1ec40110, 0x04b0400f, - 0xbd0001f6, + 0xbd000ef6, 0xc70ef404, /* 0x0328: host_send_done */ /* 0x032a: host_recv */ diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h index 5a73fa62097..254205cd516 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h @@ -1124,7 +1124,7 @@ uint32_t nva3_pwr_code[] = { 0x0f1ec401, 0x04b007f1, 0xd00604b6, - 0x04bd0001, + 0x04bd000e, /* 0x03cb: host_send_done */ 0xf8ba0ef4, /* 0x03cd: host_recv */ diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h index 4dba00d2dd1..7ac87405d01 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h @@ -1124,7 +1124,7 @@ uint32_t nvc0_pwr_code[] = { 0x0f1ec401, 0x04b007f1, 0xd00604b6, - 0x04bd0001, + 0x04bd000e, /* 0x03cb: host_send_done */ 0xf8ba0ef4, /* 0x03cd: host_recv */ diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h index 5e24c6bc041..cd9ff1a7328 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h +++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h @@ -1033,7 +1033,7 @@ uint32_t nvd0_pwr_code[] = { 0xb6026b21, 0x1ec40110, 0xb007f10f, - 0x0001d004, + 0x000ed004, 0x0ef404bd, /* 0x0365: host_send_done */ /* 0x0367: host_recv */ diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index 80e584a1bd1..9ad01da6eac 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -110,16 +110,18 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode) poll = false; break; case NOUVEAU_THERM_CTRL_AUTO: - if (priv->fan->bios.nr_fan_trip) { + switch(priv->fan->bios.fan_mode) { + case NVBIOS_THERM_FAN_TRIP: duty = nouveau_therm_update_trip(therm); - } else - if (priv->fan->bios.linear_min_temp || - priv->fan->bios.linear_max_temp) { + break; + case NVBIOS_THERM_FAN_LINEAR: duty = nouveau_therm_update_linear(therm); - } else { + break; + case NVBIOS_THERM_FAN_OTHER: if (priv->cstate) duty = priv->cstate; poll = false; + break; } immd = false; break; @@ -179,7 +181,7 @@ nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) /* do not allow automatic fan management if the thermal sensor is * not available */ - if (priv->mode == NOUVEAU_THERM_CTRL_AUTO && therm->temp_get(therm) < 0) + if (mode == NOUVEAU_THERM_CTRL_AUTO && therm->temp_get(therm) < 0) return -EINVAL; if (priv->mode == mode) diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index 95f6129eeed..016990a8252 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c @@ -54,8 +54,10 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target) /* check that we're not already at the target duty cycle */ duty = fan->get(therm); - if (duty == target) - goto done; + if (duty == target) { + spin_unlock_irqrestore(&fan->lock, flags); + return 0; + } /* smooth out the fanspeed increase/decrease */ if (!immediate && duty >= 0) { @@ -73,8 +75,15 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target) nv_debug(therm, "FAN update: %d\n", duty); ret = fan->set(therm, duty); - if (ret) - goto done; + if (ret) { + spin_unlock_irqrestore(&fan->lock, flags); + return ret; + } + + /* fan speed updated, drop the fan lock before grabbing the + * alarm-scheduling lock and risking a deadlock + */ + spin_unlock_irqrestore(&fan->lock, flags); /* schedule next fan update, if not at target speed already */ if (list_empty(&fan->alarm.head) && target != duty) { @@ -92,8 +101,6 @@ nouveau_fan_update(struct nouveau_fan *fan, bool immediate, int target) ptimer->alarm(ptimer, delay * 1000 * 1000, &fan->alarm); } -done: - spin_unlock_irqrestore(&fan->lock, flags); return ret; } @@ -185,11 +192,8 @@ nouveau_therm_fan_set_defaults(struct nouveau_therm *therm) priv->fan->bios.max_duty = 100; priv->fan->bios.bump_period = 500; priv->fan->bios.slow_down_period = 2000; -/*XXX: talk to mupuf */ -#if 0 priv->fan->bios.linear_min_temp = 40; priv->fan->bios.linear_max_temp = 85; -#endif } static void @@ -235,7 +239,8 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm) /* attempt to locate a drivable fan, and determine control method */ ret = gpio->find(gpio, 0, DCB_GPIO_FAN, 0xff, &func); if (ret == 0) { - if (func.log[0] & DCB_GPIO_LOG_DIR_IN) { + /* FIXME: is this really the place to perform such checks ? */ + if (func.line != 16 && func.log[0] & DCB_GPIO_LOG_DIR_IN) { nv_debug(therm, "GPIO_FAN is in input mode\n"); ret = -EINVAL; } else { diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c index 5f71db8e899..9a5c0734026 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fanpwm.c @@ -67,7 +67,7 @@ nouveau_fanpwm_set(struct nouveau_therm *therm, int percent) if (priv->base.bios.pwm_freq) { divs = 1; if (therm->pwm_clock) - divs = therm->pwm_clock(therm); + divs = therm->pwm_clock(therm, priv->func.line); divs /= priv->base.bios.pwm_freq; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c index 7610fc5f8fa..ca9ad9fd47b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c @@ -60,9 +60,9 @@ static struct nouveau_i2c_board_info nv_board_infos[] = { { { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 }, { { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 }, - { { I2C_BOARD_INFO("adt7473", 0x2e) }, 20 }, - { { I2C_BOARD_INFO("adt7473", 0x2d) }, 20 }, - { { I2C_BOARD_INFO("adt7473", 0x2c) }, 20 }, + { { I2C_BOARD_INFO("adt7473", 0x2e) }, 40 }, + { { I2C_BOARD_INFO("adt7473", 0x2d) }, 40 }, + { { I2C_BOARD_INFO("adt7473", 0x2c) }, 40 }, { { I2C_BOARD_INFO("f75375", 0x2e) }, 0 }, { { I2C_BOARD_INFO("lm99", 0x4c) }, 0 }, { { I2C_BOARD_INFO("lm90", 0x4c) }, 0 }, diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c index 8cf7597a218..321db927d63 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c @@ -93,7 +93,7 @@ nv50_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) } int -nv50_fan_pwm_clock(struct nouveau_therm *therm) +nv50_fan_pwm_clock(struct nouveau_therm *therm, int line) { int chipset = nv_device(therm)->chipset; int crystal = nv_device(therm)->crystal; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c index 3b2c4580098..0478b2e3fb1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c @@ -36,7 +36,7 @@ nva3_therm_fan_sense(struct nouveau_therm *therm) u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff; u32 ctrl = nv_rd32(therm, 0x00e720); if (ctrl & 0x00000001) - return tach * 60; + return tach * 60 / 2; return -ENODEV; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c index 4dd4f81ae87..bbf117be572 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c @@ -32,12 +32,15 @@ static int pwm_info(struct nouveau_therm *therm, int line) { u32 gpio = nv_rd32(therm, 0x00d610 + (line * 0x04)); + switch (gpio & 0x000000c0) { case 0x00000000: /* normal mode, possibly pwm forced off by us */ case 0x00000040: /* nvio special */ switch (gpio & 0x0000001f) { + case 0x00: return 2; case 0x19: return 1; case 0x1c: return 0; + case 0x1e: return 2; default: break; } @@ -56,8 +59,9 @@ nvd0_fan_pwm_ctrl(struct nouveau_therm *therm, int line, bool enable) int indx = pwm_info(therm, line); if (indx < 0) return indx; - - nv_mask(therm, 0x00d610 + (line * 0x04), 0x000000c0, data); + else if (indx < 2) + nv_mask(therm, 0x00d610 + (line * 0x04), 0x000000c0, data); + /* nothing to do for indx == 2, it seems hardwired to PTHERM */ return 0; } @@ -67,10 +71,15 @@ nvd0_fan_pwm_get(struct nouveau_therm *therm, int line, u32 *divs, u32 *duty) int indx = pwm_info(therm, line); if (indx < 0) return indx; - - if (nv_rd32(therm, 0x00d610 + (line * 0x04)) & 0x00000040) { - *divs = nv_rd32(therm, 0x00e114 + (indx * 8)); - *duty = nv_rd32(therm, 0x00e118 + (indx * 8)); + else if (indx < 2) { + if (nv_rd32(therm, 0x00d610 + (line * 0x04)) & 0x00000040) { + *divs = nv_rd32(therm, 0x00e114 + (indx * 8)); + *duty = nv_rd32(therm, 0x00e118 + (indx * 8)); + return 0; + } + } else if (indx == 2) { + *divs = nv_rd32(therm, 0x0200d8) & 0x1fff; + *duty = nv_rd32(therm, 0x0200dc) & 0x1fff; return 0; } @@ -83,16 +92,26 @@ nvd0_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty) int indx = pwm_info(therm, line); if (indx < 0) return indx; - - nv_wr32(therm, 0x00e114 + (indx * 8), divs); - nv_wr32(therm, 0x00e118 + (indx * 8), duty | 0x80000000); + else if (indx < 2) { + nv_wr32(therm, 0x00e114 + (indx * 8), divs); + nv_wr32(therm, 0x00e118 + (indx * 8), duty | 0x80000000); + } else if (indx == 2) { + nv_mask(therm, 0x0200d8, 0x1fff, divs); /* keep the high bits */ + nv_wr32(therm, 0x0200dc, duty | 0x40000000); + } return 0; } static int -nvd0_fan_pwm_clock(struct nouveau_therm *therm) +nvd0_fan_pwm_clock(struct nouveau_therm *therm, int line) { - return (nv_device(therm)->crystal * 1000) / 20; + int indx = pwm_info(therm, line); + if (indx < 0) + return 0; + else if (indx < 2) + return (nv_device(therm)->crystal * 1000) / 20; + else + return nv_device(therm)->crystal * 1000 / 10; } static int diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 96f8f95693c..916fca5c781 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -143,7 +143,7 @@ void nv40_therm_intr(struct nouveau_subdev *); int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool); int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *); int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32); -int nv50_fan_pwm_clock(struct nouveau_therm *); +int nv50_fan_pwm_clock(struct nouveau_therm *, int); int nv84_temp_get(struct nouveau_therm *therm); int nv84_therm_fini(struct nouveau_object *object, bool suspend); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index cfde9eb44ad..6212537b90c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -192,11 +192,11 @@ alarm_timer_callback(struct nouveau_alarm *alarm) nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_shutdown, NOUVEAU_THERM_THRS_SHUTDOWN); + spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); + /* schedule the next poll in one second */ if (therm->temp_get(therm) >= 0 && list_empty(&alarm->head)) - ptimer->alarm(ptimer, 1000 * 1000 * 1000, alarm); - - spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); + ptimer->alarm(ptimer, 1000000000ULL, alarm); } void diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/timer/gk20a.c new file mode 100644 index 00000000000..37484db1f7f --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/gk20a.c @@ -0,0 +1,57 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "nv04.h" + +static int +gk20a_timer_init(struct nouveau_object *object) +{ + struct nv04_timer_priv *priv = (void *)object; + u32 hi = upper_32_bits(priv->suspend_time); + u32 lo = lower_32_bits(priv->suspend_time); + int ret; + + ret = nouveau_timer_init(&priv->base); + if (ret) + return ret; + + nv_debug(priv, "time low : 0x%08x\n", lo); + nv_debug(priv, "time high : 0x%08x\n", hi); + + /* restore the time before suspend */ + nv_wr32(priv, NV04_PTIMER_TIME_1, hi); + nv_wr32(priv, NV04_PTIMER_TIME_0, lo); + return 0; +} + +struct nouveau_oclass +gk20a_timer_oclass = { + .handle = NV_SUBDEV(TIMER, 0xff), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv04_timer_ctor, + .dtor = nv04_timer_dtor, + .init = gk20a_timer_init, + .fini = nv04_timer_fini, + } +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index c0bdd10358d..240ed0b983a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -22,22 +22,7 @@ * Authors: Ben Skeggs */ -#include <subdev/timer.h> - -#define NV04_PTIMER_INTR_0 0x009100 -#define NV04_PTIMER_INTR_EN_0 0x009140 -#define NV04_PTIMER_NUMERATOR 0x009200 -#define NV04_PTIMER_DENOMINATOR 0x009210 -#define NV04_PTIMER_TIME_0 0x009400 -#define NV04_PTIMER_TIME_1 0x009410 -#define NV04_PTIMER_ALARM_0 0x009420 - -struct nv04_timer_priv { - struct nouveau_timer base; - struct list_head alarms; - spinlock_t lock; - u64 suspend_time; -}; +#include "nv04.h" static u64 nv04_timer_read(struct nouveau_timer *ptimer) @@ -142,35 +127,14 @@ nv04_timer_intr(struct nouveau_subdev *subdev) } } -static int -nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv04_timer_priv *priv; - int ret; - - ret = nouveau_timer_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.base.intr = nv04_timer_intr; - priv->base.read = nv04_timer_read; - priv->base.alarm = nv04_timer_alarm; - priv->base.alarm_cancel = nv04_timer_alarm_cancel; - priv->suspend_time = 0; - - INIT_LIST_HEAD(&priv->alarms); - spin_lock_init(&priv->lock); - return 0; -} - -static void -nv04_timer_dtor(struct nouveau_object *object) +int +nv04_timer_fini(struct nouveau_object *object, bool suspend) { struct nv04_timer_priv *priv = (void *)object; - return nouveau_timer_destroy(&priv->base); + if (suspend) + priv->suspend_time = nv04_timer_read(&priv->base); + nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); + return nouveau_timer_fini(&priv->base, suspend); } static int @@ -257,14 +221,35 @@ nv04_timer_init(struct nouveau_object *object) return 0; } -static int -nv04_timer_fini(struct nouveau_object *object, bool suspend) +void +nv04_timer_dtor(struct nouveau_object *object) { struct nv04_timer_priv *priv = (void *)object; - if (suspend) - priv->suspend_time = nv04_timer_read(&priv->base); - nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); - return nouveau_timer_fini(&priv->base, suspend); + return nouveau_timer_destroy(&priv->base); +} + +int +nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv04_timer_priv *priv; + int ret; + + ret = nouveau_timer_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.base.intr = nv04_timer_intr; + priv->base.read = nv04_timer_read; + priv->base.alarm = nv04_timer_alarm; + priv->base.alarm_cancel = nv04_timer_alarm_cancel; + priv->suspend_time = 0; + + INIT_LIST_HEAD(&priv->alarms); + spin_lock_init(&priv->lock); + return 0; } struct nouveau_oclass diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.h new file mode 100644 index 00000000000..4bc152697c3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.h @@ -0,0 +1,27 @@ +#ifndef __NVKM_TIMER_NV04_H__ +#define __NVKM_TIMER_NV04_H__ + +#include "priv.h" + +#define NV04_PTIMER_INTR_0 0x009100 +#define NV04_PTIMER_INTR_EN_0 0x009140 +#define NV04_PTIMER_NUMERATOR 0x009200 +#define NV04_PTIMER_DENOMINATOR 0x009210 +#define NV04_PTIMER_TIME_0 0x009400 +#define NV04_PTIMER_TIME_1 0x009410 +#define NV04_PTIMER_ALARM_0 0x009420 + +struct nv04_timer_priv { + struct nouveau_timer base; + struct list_head alarms; + spinlock_t lock; + u64 suspend_time; +}; + +int nv04_timer_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void nv04_timer_dtor(struct nouveau_object *); +int nv04_timer_fini(struct nouveau_object *, bool); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/priv.h b/drivers/gpu/drm/nouveau/core/subdev/timer/priv.h new file mode 100644 index 00000000000..799dae3f230 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/priv.h @@ -0,0 +1,6 @@ +#ifndef __NVKM_TIMER_PRIV_H__ +#define __NVKM_TIMER_PRIV_H__ + +#include <subdev/timer.h> + +#endif diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 0e3270c3ffd..41be3424c90 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -239,7 +239,7 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) struct drm_device *dev = crtc->dev; struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index]; - struct drm_framebuffer *fb = crtc->fb; + struct drm_framebuffer *fb = crtc->primary->fb; /* Calculate our timings */ int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; @@ -574,7 +574,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) regp->CRTC[NV_CIO_CRE_86] = 0x1; } - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->fb->depth + 1) / 8; + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] = (crtc->primary->fb->depth + 1) / 8; /* Enable slaved mode (called MODE_TV in nv4ref.h) */ if (lvds_output || tmds_output || tv_output) regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (1 << 7); @@ -588,7 +588,7 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) regp->ramdac_gen_ctrl = NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS | NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL | NV_PRAMDAC_GENERAL_CONTROL_PIXMIX_ON; - if (crtc->fb->depth == 16) + if (crtc->primary->fb->depth == 16) regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; if (nv_device(drm->device)->chipset >= 0x11) regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_PIPE_LONG; @@ -609,7 +609,7 @@ static int nv_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { struct nv04_display *disp = nv04_display(crtc->dev); - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); + struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); int ret; @@ -808,7 +808,7 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start, * mark the lut values as dirty by setting depth==0, and it'll be * uploaded on the first mode_set_base() */ - if (!nv_crtc->base.fb) { + if (!nv_crtc->base.primary->fb) { nv_crtc->lut.depth = 0; return; } @@ -832,7 +832,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, NV_DEBUG(drm, "index %d\n", nv_crtc->index); /* no fb bound */ - if (!atomic && !crtc->fb) { + if (!atomic && !crtc->primary->fb) { NV_DEBUG(drm, "No FB bound\n"); return 0; } @@ -844,8 +844,8 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, drm_fb = passed_fb; fb = nouveau_framebuffer(passed_fb); } else { - drm_fb = crtc->fb; - fb = nouveau_framebuffer(crtc->fb); + drm_fb = crtc->primary->fb; + fb = nouveau_framebuffer(crtc->primary->fb); } nv_crtc->fb.offset = fb->nvbo->bo.offset; @@ -857,9 +857,9 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, /* Update the framebuffer format. */ regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] &= ~3; - regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->fb->depth + 1) / 8; + regp->CRTC[NV_CIO_CRE_PIXEL_INDEX] |= (crtc->primary->fb->depth + 1) / 8; regp->ramdac_gen_ctrl &= ~NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; - if (crtc->fb->depth == 16) + if (crtc->primary->fb->depth == 16) regp->ramdac_gen_ctrl |= NV_PRAMDAC_GENERAL_CONTROL_ALT_MODE_SEL; crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_PIXEL_INDEX); NVWriteRAMDAC(dev, nv_crtc->index, NV_PRAMDAC_GENERAL_CONTROL, @@ -1048,7 +1048,7 @@ nouveau_crtc_set_config(struct drm_mode_set *set) /* get a pm reference here */ ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) + if (ret < 0 && ret != -EACCES) return ret; ret = drm_crtc_helper_set_config(set); diff --git a/drivers/gpu/drm/nouveau/dispnv04/dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c index 434b920f6bd..a96dda48718 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dac.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c @@ -414,7 +414,7 @@ static void nv04_dac_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nouveau_encoder_connector_get(nv_encoder)->base.name, nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index 7fdc51e2a57..e57babb206d 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -415,7 +415,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, /* Output property. */ if ((nv_connector->dithering_mode == DITHERING_MODE_ON) || (nv_connector->dithering_mode == DITHERING_MODE_AUTO && - encoder->crtc->fb->depth > connector->display_info.bpc * 3)) { + encoder->crtc->primary->fb->depth > connector->display_info.bpc * 3)) { if (nv_device(drm->device)->chipset == 0x11) regp->dither = savep->dither | 0x00010000; else { @@ -477,7 +477,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), + nouveau_encoder_connector_get(nv_encoder)->base.name, nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 2f1ed61f7c8..4342fdaee70 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -115,7 +115,7 @@ nv04_display_create(struct drm_device *dev) &dev->mode_config.connector_list, head) { if (!connector->encoder_ids[0]) { NV_WARN(drm, "%s has no encoders, removing\n", - drm_get_connector_name(connector)); + connector->name); connector->funcs->destroy(connector); } } diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index 244822df8ff..8667620b703 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c @@ -171,7 +171,8 @@ static void nv04_tv_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); + nouveau_encoder_connector_get(nv_encoder)->base.name, + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } static void nv04_tv_destroy(struct drm_encoder *encoder) diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index acef48f4a4e..195bd8e86c6 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -612,8 +612,7 @@ static void nv17_tv_commit(struct drm_encoder *encoder) helper->dpms(encoder, DRM_MODE_DPMS_ON); NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", - drm_get_connector_name( - &nouveau_encoder_connector_get(nv_encoder)->base), + nouveau_encoder_connector_get(nv_encoder)->base.name, nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); } diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 900fae01793..b13f441c643 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -97,6 +97,7 @@ nouveau_abi16_swclass(struct nouveau_drm *drm) case NV_C0: case NV_D0: case NV_E0: + case GM100: return 0x906e; } @@ -139,7 +140,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, /* destroy channel object, all children will be killed too */ if (chan->chan) { - abi16->handles &= ~(1 << (chan->chan->handle & 0xffff)); + abi16->handles &= ~(1ULL << (chan->chan->handle & 0xffff)); nouveau_channel_del(&chan->chan); } @@ -179,12 +180,21 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) getparam->value = device->chipset; break; case NOUVEAU_GETPARAM_PCI_VENDOR: - getparam->value = dev->pdev->vendor; + if (nv_device_is_pci(device)) + getparam->value = dev->pdev->vendor; + else + getparam->value = 0; break; case NOUVEAU_GETPARAM_PCI_DEVICE: - getparam->value = dev->pdev->device; + if (nv_device_is_pci(device)) + getparam->value = dev->pdev->device; + else + getparam->value = 0; break; case NOUVEAU_GETPARAM_BUS_TYPE: + if (!nv_device_is_pci(device)) + getparam->value = 3; + else if (drm_pci_device_is_agp(dev)) getparam->value = 0; else @@ -270,8 +280,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) return nouveau_abi16_put(abi16, -EINVAL); /* allocate "abi16 channel" data and make up a handle for it */ - init->channel = ffsll(~abi16->handles); - if (!init->channel--) + init->channel = __ffs64(~abi16->handles); + if (~abi16->handles == 0) return nouveau_abi16_put(abi16, -ENOSPC); chan = kzalloc(sizeof(*chan), GFP_KERNEL); @@ -280,7 +290,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) INIT_LIST_HEAD(&chan->notifiers); list_add(&chan->head, &abi16->channels); - abi16->handles |= (1 << init->channel); + abi16->handles |= (1ULL << init->channel); /* create channel object and initialise dma and fence management */ ret = nouveau_channel_new(drm, cli, NVDRM_DEVICE, NVDRM_CHAN | diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 4ef83df2b24..279206997e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -106,6 +106,29 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * return 0; } +/* + * On some platforms, _DSM(nouveau_op_dsm_muid, func0) has special + * requirements on the fourth parameter, so a private implementation + * instead of using acpi_check_dsm(). + */ +static int nouveau_check_optimus_dsm(acpi_handle handle) +{ + int result; + + /* + * Function 0 returns a Buffer containing available functions. + * The args parameter is ignored for function 0, so just put 0 in it + */ + if (nouveau_optimus_dsm(handle, 0, 0, &result)) + return 0; + + /* + * ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. + * If the n-th bit is enabled, function n is supported + */ + return result & 1 && result & (1 << NOUVEAU_DSM_OPTIMUS_CAPS); +} + static int nouveau_dsm(acpi_handle handle, int func, int arg) { int ret = 0; @@ -207,8 +230,7 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) 1 << NOUVEAU_DSM_POWER)) retval |= NOUVEAU_DSM_HAS_MUX; - if (acpi_check_dsm(dhandle, nouveau_op_dsm_muid, 0x00000100, - 1 << NOUVEAU_DSM_OPTIMUS_CAPS)) + if (nouveau_check_optimus_dsm(dhandle)) retval |= NOUVEAU_DSM_HAS_OPT; if (retval & NOUVEAU_DSM_HAS_OPT) { @@ -367,9 +389,6 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev) acpi_status status; acpi_handle dhandle, rom_handle; - if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected) - return false; - dhandle = ACPI_HANDLE(&pdev->dev); if (!dhandle) return false; diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c index 2953c4e91e1..51666daddb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_agp.c +++ b/drivers/gpu/drm/nouveau/nouveau_agp.c @@ -75,7 +75,7 @@ nouveau_agp_enabled(struct nouveau_drm *drm) { struct drm_device *dev = drm->dev; - if (!drm_pci_device_is_agp(dev) || !dev->agp) + if (!dev->pdev || !drm_pci_device_is_agp(dev) || !dev->agp) return false; if (drm->agp.stat == UNKNOWN) { diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 630f6e84fc0..2c1e4aad7da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -31,7 +31,6 @@ */ #include <linux/backlight.h> -#include <linux/acpi.h> #include "nouveau_drm.h" #include "nouveau_reg.h" @@ -222,14 +221,6 @@ nouveau_backlight_init(struct drm_device *dev) struct nouveau_device *device = nv_device(drm->device); struct drm_connector *connector; -#ifdef CONFIG_ACPI - if (acpi_video_backlight_support()) { - NV_INFO(drm, "ACPI backlight interface available, " - "not registering our own\n"); - return 0; - } -#endif - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && connector->connector_type != DRM_MODE_CONNECTOR_eDP) diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 4c3feaaa103..8268a4ccac1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -1474,9 +1474,12 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, case 0: entry->dpconf.link_bw = 162000; break; - default: + case 1: entry->dpconf.link_bw = 270000; break; + default: + entry->dpconf.link_bw = 540000; + break; } switch ((conf & 0x0f000000) >> 24) { case 0xf: @@ -2069,6 +2072,10 @@ nouveau_bios_init(struct drm_device *dev) struct nvbios *bios = &drm->vbios; int ret; + /* only relevant for PCI devices */ + if (!dev->pdev) + return 0; + if (!NVInitVBIOS(dev)) return -ENODEV; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 488686d490c..b6dc85c614b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1249,13 +1249,13 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) mem->bus.is_iomem = !dev->agp->cant_use_aperture; } #endif - if (!node->memtype) + if (nv_device(drm->device)->card_type < NV_50 || !node->memtype) /* untiled */ break; /* fallthrough, tiled memory */ case TTM_PL_VRAM: mem->bus.offset = mem->start << PAGE_SHIFT; - mem->bus.base = pci_resource_start(dev->pdev, 1); + mem->bus.base = nv_device_resource_start(nouveau_dev(dev), 1); mem->bus.is_iomem = true; if (nv_device(drm->device)->card_type >= NV_50) { struct nouveau_bar *bar = nouveau_bar(drm->device); @@ -1293,7 +1293,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_device *device = nv_device(drm->device); - u32 mappable = pci_resource_len(device->pdev, 1) >> PAGE_SHIFT; + u32 mappable = nv_device_resource_len(device, 1) >> PAGE_SHIFT; int ret; /* as long as the bo isn't in vram, and isn't tiled, we've got @@ -1331,6 +1331,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) { struct ttm_dma_tt *ttm_dma = (void *)ttm; struct nouveau_drm *drm; + struct nouveau_device *device; struct drm_device *dev; unsigned i; int r; @@ -1348,6 +1349,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) } drm = nouveau_bdev(ttm->bdev); + device = nv_device(drm->device); dev = drm->dev; #if __OS_HAS_AGP @@ -1368,13 +1370,12 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm) } for (i = 0; i < ttm->num_pages; i++) { - ttm_dma->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i], - 0, PAGE_SIZE, - PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->pdev, ttm_dma->dma_address[i])) { + ttm_dma->dma_address[i] = nv_device_map_page(device, + ttm->pages[i]); + if (!ttm_dma->dma_address[i]) { while (--i) { - pci_unmap_page(dev->pdev, ttm_dma->dma_address[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + nv_device_unmap_page(device, + ttm_dma->dma_address[i]); ttm_dma->dma_address[i] = 0; } ttm_pool_unpopulate(ttm); @@ -1389,6 +1390,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) { struct ttm_dma_tt *ttm_dma = (void *)ttm; struct nouveau_drm *drm; + struct nouveau_device *device; struct drm_device *dev; unsigned i; bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); @@ -1397,6 +1399,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) return; drm = nouveau_bdev(ttm->bdev); + device = nv_device(drm->device); dev = drm->dev; #if __OS_HAS_AGP @@ -1415,8 +1418,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) for (i = 0; i < ttm->num_pages; i++) { if (ttm_dma->dma_address[i]) { - pci_unmap_page(dev->pdev, ttm_dma->dma_address[i], - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + nv_device_unmap_page(device, ttm_dma->dma_address[i]); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index cc5152be2cf..ccb6b452d6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -154,7 +154,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli, * nfi why this exists, it came from the -nv ddx. */ args.flags = NV_DMA_TARGET_PCI | NV_DMA_ACCESS_RDWR; - args.start = pci_resource_start(device->pdev, 1); + args.start = nv_device_resource_start(device, 1); args.limit = args.start + limit; } else { args.flags = NV_DMA_TARGET_VRAM | NV_DMA_ACCESS_RDWR; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 1674882d60d..1fa222e8f00 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -44,6 +44,7 @@ #include <subdev/i2c.h> #include <subdev/gpio.h> +#include <engine/disp.h> MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); static int nouveau_tv_disable = 0; @@ -75,7 +76,8 @@ find_encoder(struct drm_connector *connector, int type) continue; nv_encoder = nouveau_encoder(obj_to_encoder(obj)); - if (type == DCB_OUTPUT_ANY || nv_encoder->dcb->type == type) + if (type == DCB_OUTPUT_ANY || + (nv_encoder->dcb && nv_encoder->dcb->type == type)) return nv_encoder; } @@ -100,22 +102,24 @@ static void nouveau_connector_destroy(struct drm_connector *connector) { struct nouveau_connector *nv_connector = nouveau_connector(connector); - nouveau_event_ref(NULL, &nv_connector->hpd_func); + nouveau_event_ref(NULL, &nv_connector->hpd); kfree(nv_connector->edid); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); + if (nv_connector->aux.transfer) + drm_dp_aux_unregister(&nv_connector->aux); kfree(connector); } -static struct nouveau_i2c_port * -nouveau_connector_ddc_detect(struct drm_connector *connector, - struct nouveau_encoder **pnv_encoder) +static struct nouveau_encoder * +nouveau_connector_ddc_detect(struct drm_connector *connector) { struct drm_device *dev = connector->dev; struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_gpio *gpio = nouveau_gpio(drm->device); - struct nouveau_i2c_port *port = NULL; + struct nouveau_encoder *nv_encoder; + struct drm_mode_object *obj; int i, panel = -ENODEV; /* eDP panels need powering on by us (if the VBIOS doesn't default it @@ -130,13 +134,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, } } - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { - struct nouveau_encoder *nv_encoder; - struct drm_mode_object *obj; - int id; - - id = connector->encoder_ids[i]; - if (!id) + for (i = 0; nv_encoder = NULL, i < DRM_CONNECTOR_MAX_ENCODER; i++) { + int id = connector->encoder_ids[i]; + if (id == 0) break; obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); @@ -144,22 +144,24 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, continue; nv_encoder = nouveau_encoder(obj_to_encoder(obj)); - port = nv_encoder->i2c; - if (port && nv_probe_i2c(port, 0x50)) { - *pnv_encoder = nv_encoder; - break; + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { + int ret = nouveau_dp_detect(nv_encoder); + if (ret == 0) + break; + } else + if (nv_encoder->i2c) { + if (nv_probe_i2c(nv_encoder->i2c, 0x50)) + break; } - - port = NULL; } /* eDP panel not detected, restore panel power GPIO to previous * state to avoid confusing the SOR for other output types. */ - if (!port && panel == 0) + if (!nv_encoder && panel == 0) gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); - return port; + return nv_encoder; } static struct nouveau_encoder * @@ -255,28 +257,20 @@ nouveau_connector_detect(struct drm_connector *connector, bool force) } ret = pm_runtime_get_sync(connector->dev->dev); - if (ret < 0) + if (ret < 0 && ret != -EACCES) return conn_status; - i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); - if (i2c) { + nv_encoder = nouveau_connector_ddc_detect(connector); + if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { nv_connector->edid = drm_get_edid(connector, &i2c->adapter); drm_mode_connector_update_edid_property(connector, nv_connector->edid); if (!nv_connector->edid) { NV_ERROR(drm, "DDC responded, but no EDID for %s\n", - drm_get_connector_name(connector)); + connector->name); goto detect_analog; } - if (nv_encoder->dcb->type == DCB_OUTPUT_DP && - !nouveau_dp_detect(to_drm_encoder(nv_encoder))) { - NV_ERROR(drm, "Detected %s, but failed init\n", - drm_get_connector_name(connector)); - conn_status = connector_status_disconnected; - goto out; - } - /* Override encoder type for DVI-I based on whether EDID * says the display is digital or analog, both use the * same i2c channel so the value returned from ddc_detect @@ -437,7 +431,7 @@ nouveau_connector_force(struct drm_connector *connector) nv_encoder = find_encoder(connector, type); if (!nv_encoder) { NV_ERROR(drm, "can't find encoder to force %s on!\n", - drm_get_connector_name(connector)); + connector->name); connector->status = connector_status_disconnected; return; } @@ -912,33 +906,103 @@ nouveau_connector_funcs_lvds = { }; static void +nouveau_connector_dp_dpms(struct drm_connector *connector, int mode) +{ + struct nouveau_encoder *nv_encoder = NULL; + + if (connector->encoder) + nv_encoder = nouveau_encoder(connector->encoder); + if (nv_encoder && nv_encoder->dcb && + nv_encoder->dcb->type == DCB_OUTPUT_DP) { + if (mode == DRM_MODE_DPMS_ON) { + u8 data = DP_SET_POWER_D0; + nv_wraux(nv_encoder->i2c, DP_SET_POWER, &data, 1); + usleep_range(1000, 2000); + } else { + u8 data = DP_SET_POWER_D3; + nv_wraux(nv_encoder->i2c, DP_SET_POWER, &data, 1); + } + } + + drm_helper_connector_dpms(connector, mode); +} + +static const struct drm_connector_funcs +nouveau_connector_funcs_dp = { + .dpms = nouveau_connector_dp_dpms, + .save = NULL, + .restore = NULL, + .detect = nouveau_connector_detect, + .destroy = nouveau_connector_destroy, + .fill_modes = drm_helper_probe_single_connector_modes, + .set_property = nouveau_connector_set_property, + .force = nouveau_connector_force +}; + +static void nouveau_connector_hotplug_work(struct work_struct *work) { struct nouveau_connector *nv_connector = - container_of(work, struct nouveau_connector, hpd_work); + container_of(work, typeof(*nv_connector), work); struct drm_connector *connector = &nv_connector->base; - struct drm_device *dev = connector->dev; - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_gpio *gpio = nouveau_gpio(drm->device); - bool plugged = gpio->get(gpio, 0, nv_connector->hpd.func, 0xff); + struct nouveau_drm *drm = nouveau_drm(connector->dev); + const char *name = connector->name; - NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", - drm_get_connector_name(connector)); + if (nv_connector->status & NVKM_HPD_IRQ) { + } else { + bool plugged = (nv_connector->status != NVKM_HPD_UNPLUG); - if (plugged) - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); - else - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); - drm_helper_hpd_irq_event(dev); + if (plugged) + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); + else + drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); + drm_helper_hpd_irq_event(connector->dev); + } + + nouveau_event_get(nv_connector->hpd); } static int -nouveau_connector_hotplug(void *data, int index) +nouveau_connector_hotplug(void *data, u32 type, int index) { struct nouveau_connector *nv_connector = data; - schedule_work(&nv_connector->hpd_work); - return NVKM_EVENT_KEEP; + nv_connector->status = type; + schedule_work(&nv_connector->work); + return NVKM_EVENT_DROP; +} + +static ssize_t +nouveau_connector_aux_xfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) +{ + struct nouveau_connector *nv_connector = + container_of(aux, typeof(*nv_connector), aux); + struct nouveau_encoder *nv_encoder; + struct nouveau_i2c_port *port; + int ret; + + nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP); + if (!nv_encoder || !(port = nv_encoder->i2c)) + return -ENODEV; + if (WARN_ON(msg->size > 16)) + return -E2BIG; + if (msg->size == 0) + return msg->size; + + ret = nouveau_i2c(port)->acquire(port, 0); + if (ret) + return ret; + + ret = port->func->aux(port, false, msg->request, msg->address, + msg->buffer, msg->size); + nouveau_i2c(port)->release(port); + if (ret >= 0) { + msg->reply = ret; + return msg->size; + } + + return ret; } static int @@ -960,7 +1024,8 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb) case DCB_CONNECTOR_DP : return DRM_MODE_CONNECTOR_DisplayPort; case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP; case DCB_CONNECTOR_HDMI_0 : - case DCB_CONNECTOR_HDMI_1 : return DRM_MODE_CONNECTOR_HDMIA; + case DCB_CONNECTOR_HDMI_1 : + case DCB_CONNECTOR_HDMI_C : return DRM_MODE_CONNECTOR_HDMIA; default: break; } @@ -973,9 +1038,9 @@ nouveau_connector_create(struct drm_device *dev, int index) { const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_gpio *gpio = nouveau_gpio(drm->device); struct nouveau_display *disp = nouveau_display(dev); struct nouveau_connector *nv_connector = NULL; + struct nouveau_disp *pdisp = nouveau_disp(drm->device); struct drm_connector *connector; int type, ret = 0; bool dummy; @@ -991,33 +1056,15 @@ nouveau_connector_create(struct drm_device *dev, int index) return ERR_PTR(-ENOMEM); connector = &nv_connector->base; - INIT_WORK(&nv_connector->hpd_work, nouveau_connector_hotplug_work); nv_connector->index = index; /* attempt to parse vbios connector type and hotplug gpio */ nv_connector->dcb = olddcb_conn(dev, index); if (nv_connector->dcb) { - static const u8 hpd[16] = { - 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60, - }; - u32 entry = ROM16(nv_connector->dcb[0]); if (olddcb_conntab(dev)[3] >= 4) entry |= (u32)ROM16(nv_connector->dcb[2]) << 16; - ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)], - DCB_GPIO_UNUSED, &nv_connector->hpd); - if (ret) - nv_connector->hpd.func = DCB_GPIO_UNUSED; - - if (nv_connector->hpd.func != DCB_GPIO_UNUSED) { - nouveau_event_new(gpio->events, nv_connector->hpd.line, - nouveau_connector_hotplug, - nv_connector, - &nv_connector->hpd_func); - } - nv_connector->type = nv_connector->dcb[0]; if (drm_conntype_from_dcb(nv_connector->type) == DRM_MODE_CONNECTOR_Unknown) { @@ -1039,7 +1086,6 @@ nouveau_connector_create(struct drm_device *dev, int index) } } else { nv_connector->type = DCB_CONNECTOR_NONE; - nv_connector->hpd.func = DCB_GPIO_UNUSED; } /* no vbios data, or an unknown dcb connector type - attempt to @@ -1079,8 +1125,8 @@ nouveau_connector_create(struct drm_device *dev, int index) } } - type = drm_conntype_from_dcb(nv_connector->type); - if (type == DRM_MODE_CONNECTOR_LVDS) { + switch ((type = drm_conntype_from_dcb(nv_connector->type))) { + case DRM_MODE_CONNECTOR_LVDS: ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); if (ret) { NV_ERROR(drm, "Error parsing LVDS table, disabling\n"); @@ -1089,8 +1135,23 @@ nouveau_connector_create(struct drm_device *dev, int index) } funcs = &nouveau_connector_funcs_lvds; - } else { + break; + case DRM_MODE_CONNECTOR_DisplayPort: + case DRM_MODE_CONNECTOR_eDP: + nv_connector->aux.dev = dev->dev; + nv_connector->aux.transfer = nouveau_connector_aux_xfer; + ret = drm_dp_aux_register(&nv_connector->aux); + if (ret) { + NV_ERROR(drm, "failed to register aux channel\n"); + kfree(nv_connector); + return ERR_PTR(ret); + } + + funcs = &nouveau_connector_funcs_dp; + break; + default: funcs = &nouveau_connector_funcs; + break; } /* defaults, will get overridden in detect() */ @@ -1165,10 +1226,16 @@ nouveau_connector_create(struct drm_device *dev, int index) break; } - connector->polled = DRM_CONNECTOR_POLL_CONNECT; - if (nv_connector->hpd.func != DCB_GPIO_UNUSED) + ret = nouveau_event_new(pdisp->hpd, NVKM_HPD, index, + nouveau_connector_hotplug, + nv_connector, &nv_connector->hpd); + if (ret) + connector->polled = DRM_CONNECTOR_POLL_CONNECT; + else connector->polled = DRM_CONNECTOR_POLL_HPD; + INIT_WORK(&nv_connector->work, nouveau_connector_hotplug_work); + drm_sysfs_connector_add(connector); return connector; } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index 264a778f473..8861b6c579a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -28,12 +28,12 @@ #define __NOUVEAU_CONNECTOR_H__ #include <drm/drm_edid.h> +#include <drm/drm_dp_helper.h> #include "nouveau_crtc.h" #include <core/event.h> #include <subdev/bios.h> -#include <subdev/bios/gpio.h> struct nouveau_i2c_port; @@ -67,9 +67,11 @@ struct nouveau_connector { u8 index; u8 *dcb; - struct dcb_gpio_func hpd; - struct work_struct hpd_work; - struct nouveau_eventh *hpd_func; + struct nouveau_eventh *hpd; + u32 status; + struct work_struct work; + + struct drm_dp_aux aux; int dithering_mode; int dithering_depth; diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index d1e5890784d..a0534489d23 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h @@ -74,7 +74,7 @@ struct nouveau_crtc { static inline struct nouveau_crtc *nouveau_crtc(struct drm_crtc *crtc) { - return container_of(crtc, struct nouveau_crtc, base); + return crtc ? container_of(crtc, struct nouveau_crtc, base) : NULL; } static inline struct drm_crtc *to_drm_crtc(struct nouveau_crtc *crtc) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 24011596af4..47ad74255bf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -42,7 +42,7 @@ #include <core/class.h> static int -nouveau_display_vblank_handler(void *data, int head) +nouveau_display_vblank_handler(void *data, u32 type, int head) { struct nouveau_drm *drm = data; drm_handle_vblank(drm->dev, head); @@ -105,7 +105,7 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, if (retry) ndelay(crtc->linedur_ns); } while (retry--); - *hpos = calc(args.hblanks, args.hblanke, args.htotal, args.hline); + *hpos = args.hline; *vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline); if (stime) *stime = ns_to_ktime(args.time[0]); if (etime) *etime = ns_to_ktime(args.time[1]); @@ -178,7 +178,7 @@ nouveau_display_vblank_init(struct drm_device *dev) return -ENOMEM; for (i = 0; i < dev->mode_config.num_crtc; i++) { - ret = nouveau_event_new(pdisp->vblank, i, + ret = nouveau_event_new(pdisp->vblank, 1, i, nouveau_display_vblank_handler, drm, &disp->vblank[i]); if (ret) { @@ -393,7 +393,7 @@ nouveau_display_init(struct drm_device *dev) /* enable hotplug interrupts */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - if (conn->hpd_func) nouveau_event_get(conn->hpd_func); + if (conn->hpd) nouveau_event_get(conn->hpd); } return ret; @@ -408,7 +408,7 @@ nouveau_display_fini(struct drm_device *dev) /* disable hotplug interrupts */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - if (conn->hpd_func) nouveau_event_put(conn->hpd_func); + if (conn->hpd) nouveau_event_put(conn->hpd); } drm_kms_helper_poll_disable(dev); @@ -419,6 +419,7 @@ int nouveau_display_create(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_device *device = nouveau_dev(dev); struct nouveau_display *disp; int ret, gen; @@ -459,7 +460,7 @@ nouveau_display_create(struct drm_device *dev) } dev->mode_config.funcs = &nouveau_mode_config_funcs; - dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); + dev->mode_config.fb_base = nv_device_resource_start(device, 1); dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; @@ -488,6 +489,7 @@ nouveau_display_create(struct drm_device *dev) if (drm->vbios.dcb.entries) { static const u16 oclass[] = { + GM107_DISP_CLASS, NVF0_DISP_CLASS, NVE0_DISP_CLASS, NVD0_DISP_CLASS, @@ -569,7 +571,7 @@ nouveau_display_suspend(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; - nouveau_fb = nouveau_framebuffer(crtc->fb); + nouveau_fb = nouveau_framebuffer(crtc->primary->fb); if (!nouveau_fb || !nouveau_fb->nvbo) continue; @@ -596,7 +598,7 @@ nouveau_display_repin(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; - nouveau_fb = nouveau_framebuffer(crtc->fb); + nouveau_fb = nouveau_framebuffer(crtc->primary->fb); if (!nouveau_fb || !nouveau_fb->nvbo) continue; @@ -693,7 +695,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; struct drm_device *dev = crtc->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; + struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; struct nouveau_page_flip_state *s; struct nouveau_channel *chan = drm->channel; @@ -734,6 +736,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, fb->bits_per_pixel, fb->pitches[0], crtc->x, crtc->y, new_bo->bo.offset }; + /* Keep vblanks on during flip, for the target crtc of this flip */ + drm_vblank_get(dev, nouveau_crtc(crtc)->index); + /* Emit a page flip */ if (nv_device(drm->device)->card_type >= NV_50) { ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); @@ -762,12 +767,12 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, } ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); - mutex_unlock(&chan->cli->mutex); if (ret) goto fail_unreserve; + mutex_unlock(&chan->cli->mutex); /* Update the crtc struct and cleanup */ - crtc->fb = fb; + crtc->primary->fb = fb; nouveau_bo_fence(old_bo, fence); ttm_bo_unreserve(&old_bo->bo); @@ -777,6 +782,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, return 0; fail_unreserve: + drm_vblank_put(dev, nouveau_crtc(crtc)->index); ttm_bo_unreserve(&old_bo->bo); fail_unpin: mutex_unlock(&chan->cli->mutex); @@ -796,6 +802,7 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, struct drm_device *dev = drm->dev; struct nouveau_page_flip_state *s; unsigned long flags; + int crtcid = -1; spin_lock_irqsave(&dev->event_lock, flags); @@ -806,8 +813,16 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, } s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); - if (s->event) - drm_send_vblank_event(dev, s->crtc, s->event); + if (s->event) { + /* Vblank timestamps/counts are only correct on >= NV-50 */ + if (nv_device(drm->device)->card_type >= NV_50) + crtcid = s->crtc; + + drm_send_vblank_event(dev, crtcid, s->event); + } + + /* Give up ownership of vblank for page-flipped crtc */ + drm_vblank_put(dev, s->crtc); list_del(&s->head); if (ps) diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 36fd2250056..5675ffc175a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -55,11 +55,10 @@ nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, } -bool -nouveau_dp_detect(struct drm_encoder *encoder) +int +nouveau_dp_detect(struct nouveau_encoder *nv_encoder) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct drm_device *dev = encoder->dev; + struct drm_device *dev = nv_encoder->base.base.dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_i2c_port *auxch; u8 *dpcd = nv_encoder->dp.dpcd; @@ -67,11 +66,11 @@ nouveau_dp_detect(struct drm_encoder *encoder) auxch = nv_encoder->i2c; if (!auxch) - return false; + return -ENODEV; ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8); if (ret) - return false; + return ret; nv_encoder->dp.link_bw = 27000 * dpcd[1]; nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; @@ -91,6 +90,5 @@ nouveau_dp_detect(struct drm_encoder *encoder) nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); nouveau_dp_probe_oui(dev, auxch, dpcd); - - return true; + return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 78c8e7146d5..5425ffe3931 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -33,6 +33,7 @@ #include <core/client.h> #include <core/gpuobj.h> #include <core/class.h> +#include <core/option.h> #include <engine/device.h> #include <engine/disp.h> @@ -81,7 +82,7 @@ module_param_named(runpm, nouveau_runtime_pm, int, 0400); static struct drm_driver driver; static u64 -nouveau_name(struct pci_dev *pdev) +nouveau_pci_name(struct pci_dev *pdev) { u64 name = (u64)pci_domain_nr(pdev->bus) << 32; name |= pdev->bus->number << 16; @@ -89,15 +90,30 @@ nouveau_name(struct pci_dev *pdev) return name | PCI_FUNC(pdev->devfn); } +static u64 +nouveau_platform_name(struct platform_device *platformdev) +{ + return platformdev->id; +} + +static u64 +nouveau_name(struct drm_device *dev) +{ + if (dev->pdev) + return nouveau_pci_name(dev->pdev); + else + return nouveau_platform_name(dev->platformdev); +} + static int -nouveau_cli_create(struct pci_dev *pdev, const char *name, +nouveau_cli_create(u64 name, const char *sname, int size, void **pcli) { struct nouveau_cli *cli; int ret; *pcli = NULL; - ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, + ret = nouveau_client_create_(sname, name, nouveau_config, nouveau_debug, size, pcli); cli = *pcli; if (ret) { @@ -281,7 +297,8 @@ static int nouveau_drm_probe(struct pci_dev *pdev, remove_conflicting_framebuffers(aper, "nouveaufb", boot); kfree(aper); - ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev), + ret = nouveau_device_create(pdev, NOUVEAU_BUS_PCI, + nouveau_pci_name(pdev), pci_name(pdev), nouveau_config, nouveau_debug, &device); if (ret) return ret; @@ -300,22 +317,27 @@ static int nouveau_drm_probe(struct pci_dev *pdev, #define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403 static void -nouveau_get_hdmi_dev(struct drm_device *dev) +nouveau_get_hdmi_dev(struct nouveau_drm *drm) { - struct nouveau_drm *drm = dev->dev_private; - struct pci_dev *pdev = dev->pdev; + struct pci_dev *pdev = drm->dev->pdev; + + if (!pdev) { + DRM_INFO("not a PCI device; no HDMI\n"); + drm->hdmi_device = NULL; + return; + } /* subfunction one is a hdmi audio device? */ drm->hdmi_device = pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(PCI_SLOT(pdev->devfn), 1)); if (!drm->hdmi_device) { - DRM_INFO("hdmi device not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1); + NV_DEBUG(drm, "hdmi device not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1); return; } if ((drm->hdmi_device->class >> 8) != PCI_CLASS_MULTIMEDIA_HD_AUDIO) { - DRM_INFO("possible hdmi device not audio %d\n", drm->hdmi_device->class); + NV_DEBUG(drm, "possible hdmi device not audio %d\n", drm->hdmi_device->class); pci_dev_put(drm->hdmi_device); drm->hdmi_device = NULL; return; @@ -330,22 +352,24 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) struct nouveau_drm *drm; int ret; - ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm); + ret = nouveau_cli_create(nouveau_name(dev), "DRM", sizeof(*drm), + (void **)&drm); if (ret) return ret; dev->dev_private = drm; drm->dev = dev; + nouveau_client(drm)->debug = nouveau_dbgopt(nouveau_debug, "DRM"); INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); - nouveau_get_hdmi_dev(dev); + nouveau_get_hdmi_dev(drm); /* make sure AGP controller is in a consistent state before we * (possibly) execute vbios init tables (see nouveau_agp.h) */ - if (drm_pci_device_is_agp(dev) && dev->agp) { + if (pdev && drm_pci_device_is_agp(dev) && dev->agp) { /* dummy device object, doesn't init anything, but allows * agp code access to registers */ @@ -376,6 +400,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) if (ret) goto fail_device; + dev->irq_enabled = true; + /* workaround an odd issue on nvc1 by disabling the device's * nosnoop capability. hopefully won't cause issues until a * better fix is found - assuming there is one... @@ -475,6 +501,7 @@ nouveau_drm_remove(struct pci_dev *pdev) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_object *device; + dev->irq_enabled = false; device = drm->client.base.device; drm_put_dev(dev); @@ -483,13 +510,13 @@ nouveau_drm_remove(struct pci_dev *pdev) } static int -nouveau_do_suspend(struct drm_device *dev) +nouveau_do_suspend(struct drm_device *dev, bool runtime) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_cli *cli; int ret; - if (dev->mode_config.num_crtc) { + if (dev->mode_config.num_crtc && !runtime) { NV_INFO(drm, "suspending display...\n"); ret = nouveau_display_suspend(dev); if (ret) @@ -563,7 +590,7 @@ int nouveau_pmops_suspend(struct device *dev) if (drm_dev->mode_config.num_crtc) nouveau_fbcon_set_suspend(drm_dev, 1); - ret = nouveau_do_suspend(drm_dev); + ret = nouveau_do_suspend(drm_dev, false); if (ret) return ret; @@ -625,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev) ret = nouveau_do_resume(drm_dev); if (ret) return ret; - if (drm_dev->mode_config.num_crtc) - nouveau_fbcon_set_suspend(drm_dev, 0); - nouveau_fbcon_zfill_all(drm_dev); - if (drm_dev->mode_config.num_crtc) + if (drm_dev->mode_config.num_crtc) { nouveau_display_resume(drm_dev); + nouveau_fbcon_set_suspend(drm_dev, 0); + } + return 0; } @@ -643,7 +670,7 @@ static int nouveau_pmops_freeze(struct device *dev) if (drm_dev->mode_config.num_crtc) nouveau_fbcon_set_suspend(drm_dev, 1); - ret = nouveau_do_suspend(drm_dev); + ret = nouveau_do_suspend(drm_dev, false); return ret; } @@ -656,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev) ret = nouveau_do_resume(drm_dev); if (ret) return ret; - if (drm_dev->mode_config.num_crtc) - nouveau_fbcon_set_suspend(drm_dev, 0); - nouveau_fbcon_zfill_all(drm_dev); - if (drm_dev->mode_config.num_crtc) + + if (drm_dev->mode_config.num_crtc) { nouveau_display_resume(drm_dev); + nouveau_fbcon_set_suspend(drm_dev, 0); + } + return 0; } @@ -668,7 +696,6 @@ static int nouveau_pmops_thaw(struct device *dev) static int nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) { - struct pci_dev *pdev = dev->pdev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_cli *cli; char name[32], tmpname[TASK_COMM_LEN]; @@ -676,13 +703,15 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) /* need to bring up power immediately if opening device */ ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) + if (ret < 0 && ret != -EACCES) return ret; get_task_comm(tmpname, current); snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid)); - ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli); + ret = nouveau_cli_create(nouveau_name(dev), name, sizeof(*cli), + (void **)&cli); + if (ret) goto out_suspend; @@ -759,7 +788,7 @@ long nouveau_drm_ioctl(struct file *filp, dev = file_priv->minor->dev; ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) + if (ret < 0 && ret != -EACCES) return ret; ret = drm_ioctl(filp, cmd, arg); @@ -863,20 +892,23 @@ static int nouveau_pmops_runtime_suspend(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; - if (nouveau_runtime_pm == 0) - return -EINVAL; + if (nouveau_runtime_pm == 0) { + pm_runtime_forbid(dev); + return -EBUSY; + } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); - return -EINVAL; + pm_runtime_forbid(dev); + return -EBUSY; } nv_debug_level(SILENT); drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); nouveau_switcheroo_optimus_dsm(); - ret = nouveau_do_suspend(drm_dev); + ret = nouveau_do_suspend(drm_dev, true); pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3cold); @@ -902,8 +934,6 @@ static int nouveau_pmops_runtime_resume(struct device *dev) pci_set_master(pdev); ret = nouveau_do_resume(drm_dev); - if (drm_dev->mode_config.num_crtc) - nouveau_display_resume(drm_dev); drm_kms_helper_poll_enable(drm_dev); /* do magic */ nv_mask(device, 0x88488, (1 << 25), (1 << 25)); @@ -920,12 +950,15 @@ static int nouveau_pmops_runtime_idle(struct device *dev) struct nouveau_drm *drm = nouveau_drm(drm_dev); struct drm_crtc *crtc; - if (nouveau_runtime_pm == 0) + if (nouveau_runtime_pm == 0) { + pm_runtime_forbid(dev); return -EBUSY; + } /* are we optimus enabled? */ if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) { DRM_DEBUG_DRIVER("failing to power off - not optimus\n"); + pm_runtime_forbid(dev); return -EBUSY; } @@ -971,6 +1004,25 @@ nouveau_drm_pci_driver = { .driver.pm = &nouveau_pm_ops, }; +int nouveau_drm_platform_probe(struct platform_device *pdev) +{ + struct nouveau_device *device; + int ret; + + ret = nouveau_device_create(pdev, NOUVEAU_BUS_PLATFORM, + nouveau_platform_name(pdev), + dev_name(&pdev->dev), nouveau_config, + nouveau_debug, &device); + + ret = drm_platform_init(&driver, pdev); + if (ret) { + nouveau_object_ref(NULL, (struct nouveau_object **)&device); + return ret; + } + + return ret; +} + static int __init nouveau_drm_init(void) { diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 23ca7a51724..7efbafaf7c1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -161,10 +161,7 @@ int nouveau_pmops_resume(struct device *); #define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args) #define NV_WARN(cli, fmt, args...) nv_warn((cli), fmt, ##args) #define NV_INFO(cli, fmt, args...) nv_info((cli), fmt, ##args) -#define NV_DEBUG(cli, fmt, args...) do { \ - if (drm_debug & DRM_UT_DRIVER) \ - nv_info((cli), fmt, ##args); \ -} while (0) +#define NV_DEBUG(cli, fmt, args...) nv_debug((cli), fmt, ##args) extern int nouveau_modeset; diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index 24660c0f713..5f0e37fc284 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -46,6 +46,7 @@ struct nouveau_encoder { /* different to drm_encoder.crtc, this reflects what's * actually programmed on the hw, not the proposed crtc */ struct drm_crtc *crtc; + u32 ctrl; struct drm_display_mode mode; int last_dpms; @@ -84,9 +85,7 @@ get_slave_funcs(struct drm_encoder *enc) } /* nouveau_dp.c */ -bool nouveau_dp_detect(struct drm_encoder *); -void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate, - struct nouveau_object *); +int nouveau_dp_detect(struct nouveau_encoder *); struct nouveau_connector * nouveau_encoder_connector_get(struct nouveau_encoder *encoder); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 7903e0ed3c7..191665ee7f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -528,20 +528,13 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) struct nouveau_drm *drm = nouveau_drm(dev); if (drm->fbcon) { console_lock(); - if (state == 0) + if (state == 1) nouveau_fbcon_save_disable_accel(dev); fb_set_suspend(drm->fbcon->helper.fbdev, state); - if (state == 1) + if (state == 0) { nouveau_fbcon_restore_accel(dev); + nouveau_fbcon_zfill(dev, drm->fbcon); + } console_unlock(); } } - -void -nouveau_fbcon_zfill_all(struct drm_device *dev) -{ - struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { - nouveau_fbcon_zfill(dev, drm->fbcon); - } -} diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index fdfc0c94fbc..fcff797d208 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info); int nouveau_fbcon_init(struct drm_device *dev); void nouveau_fbcon_fini(struct drm_device *dev); void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); -void nouveau_fbcon_zfill_all(struct drm_device *dev); void nouveau_fbcon_save_disable_accel(struct drm_device *dev); void nouveau_fbcon_restore_accel(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 90074d620e3..ab5ea3b0d66 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -166,7 +166,7 @@ nouveau_fence_done(struct nouveau_fence *fence) } static int -nouveau_fence_wait_uevent_handler(void *data, int index) +nouveau_fence_wait_uevent_handler(void *data, u32 type, int index) { struct nouveau_fence_priv *priv = data; wake_up_all(&priv->waiting); @@ -183,7 +183,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) struct nouveau_eventh *handler; int ret = 0; - ret = nouveau_event_new(pfifo->uevent, 0, + ret = nouveau_event_new(pfifo->uevent, 1, 0, nouveau_fence_wait_uevent_handler, priv, &handler); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 27c3fd89e8c..c90c0dc0afe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -228,8 +228,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, struct nouveau_bo *nvbo = NULL; int ret = 0; - drm->ttm.bdev.dev_mapping = drm->dev->dev_mapping; - if (!pfb->memtype_valid(pfb, req->info.tile_flags)) { NV_ERROR(cli, "bad page flags: 0x%08x\n", req->info.tile_flags); return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c index 4aff04fa483..19fd767bab1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c @@ -383,8 +383,9 @@ nouveau_hwmon_set_pwm1_enable(struct device *d, struct device_attribute *a, long value; int ret; - if (strict_strtol(buf, 10, &value) == -EINVAL) - return -EINVAL; + ret = kstrtol(buf, 10, &value); + if (ret) + return ret; ret = therm->attr_set(therm, NOUVEAU_THERM_ATTR_FAN_MODE, value); if (ret) @@ -587,18 +588,14 @@ nouveau_hwmon_init(struct drm_device *dev) /* set the default attributes */ ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup); - if (ret) { - if (ret) - goto error; - } + if (ret) + goto error; /* if the card has a working thermal sensor */ if (therm->temp_get(therm) >= 0) { ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup); - if (ret) { - if (ret) - goto error; - } + if (ret) + goto error; } /* if the card has a pwm fan */ diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c index c1a7e5a73a2..462679a8fec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ioc32.c +++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c @@ -57,7 +57,7 @@ long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, return drm_compat_ioctl(filp, cmd, arg); #if 0 - if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) + if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(mga_compat_ioctls)) fn = nouveau_compat_ioctls[nr - DRM_COMMAND_BASE]; #endif if (fn != NULL) diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c index 89201a17ce7..75dda2b0717 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c @@ -30,7 +30,7 @@ static inline struct drm_device * drm_device(struct device *d) { - return pci_get_drvdata(to_pci_dev(d)); + return dev_get_drvdata(d); } #define snappendf(p,r,f,a...) do { \ @@ -132,9 +132,10 @@ nouveau_sysfs_fini(struct drm_device *dev) { struct nouveau_sysfs *sysfs = nouveau_sysfs(dev); struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_device *device = nv_device(drm->device); if (sysfs->ctrl) { - device_remove_file(&dev->pdev->dev, &dev_attr_pstate); + device_remove_file(nv_device_base(device), &dev_attr_pstate); nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL); } @@ -146,6 +147,7 @@ int nouveau_sysfs_init(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_device *device = nv_device(drm->device); struct nouveau_sysfs *sysfs; int ret; @@ -156,7 +158,7 @@ nouveau_sysfs_init(struct drm_device *dev) ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL, NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); if (ret == 0) - device_create_file(&dev->pdev->dev, &dev_attr_pstate); + device_create_file(nv_device_base(device), &dev_attr_pstate); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index d45d50da978..ab0228f640a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -354,21 +354,26 @@ int nouveau_ttm_init(struct nouveau_drm *drm) { struct drm_device *dev = drm->dev; + struct nouveau_device *device = nv_device(drm->device); u32 bits; int ret; bits = nouveau_vmmgr(drm->device)->dma_bits; - if ( drm->agp.stat == ENABLED || - !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits))) - bits = 32; - - ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); - if (ret) - return ret; - - ret = pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); - if (ret) - pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32)); + if (nv_device_is_pci(device)) { + if (drm->agp.stat == ENABLED || + !pci_dma_supported(dev->pdev, DMA_BIT_MASK(bits))) + bits = 32; + + ret = pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(bits)); + if (ret) + return ret; + + ret = pci_set_consistent_dma_mask(dev->pdev, + DMA_BIT_MASK(bits)); + if (ret) + pci_set_consistent_dma_mask(dev->pdev, + DMA_BIT_MASK(32)); + } ret = nouveau_ttm_global_init(drm); if (ret) @@ -376,7 +381,9 @@ nouveau_ttm_init(struct nouveau_drm *drm) ret = ttm_bo_device_init(&drm->ttm.bdev, drm->ttm.bo_global_ref.ref.object, - &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET, + &nouveau_bo_driver, + dev->anon_inode->i_mapping, + DRM_FILE_PAGE_OFFSET, bits <= 32 ? true : false); if (ret) { NV_ERROR(drm, "error initialising bo driver, %d\n", ret); @@ -394,8 +401,8 @@ nouveau_ttm_init(struct nouveau_drm *drm) return ret; } - drm->ttm.mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 1), - pci_resource_len(dev->pdev, 1)); + drm->ttm.mtrr = arch_phys_wc_add(nv_device_resource_start(device, 1), + nv_device_resource_len(device, 1)); /* GART init */ if (drm->agp.stat != ENABLED) { diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index 81638d7f2ef..4f4c3fec691 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -14,7 +14,9 @@ nouveau_vga_set_decode(void *priv, bool state) { struct nouveau_device *device = nouveau_dev(priv); - if (device->chipset >= 0x40) + if (device->card_type == NV_40 && device->chipset >= 0x4c) + nv_wr32(device, 0x088060, state); + else if (device->chipset >= 0x40) nv_wr32(device, 0x088054, state); else nv_wr32(device, 0x001854, state); @@ -62,12 +64,13 @@ static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); - bool can_switch; - spin_lock(&dev->count_lock); - can_switch = (dev->open_count == 0); - spin_unlock(&dev->count_lock); - return can_switch; + /* + * FIXME: open_count is protected by drm_global_mutex but that would lead to + * locking inversion with the driver load path. And the access here is + * completely racy anyway. So don't bother with locking for now. + */ + return dev->open_count == 0; } static const struct vga_switcheroo_client_ops @@ -82,6 +85,11 @@ nouveau_vga_init(struct nouveau_drm *drm) { struct drm_device *dev = drm->dev; bool runtime = false; + + /* only relevant for PCI devices */ + if (!dev->pdev) + return; + vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); if (nouveau_runtime_pm == 1) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 2dccafc6e9d..4c534b7b04d 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1,4 +1,4 @@ - /* +/* * Copyright 2011 Red Hat Inc. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -26,6 +26,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_dp_helper.h> #include "nouveau_drm.h" #include "nouveau_dma.h" @@ -651,7 +652,7 @@ nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) nv_connector = nouveau_crtc_connector_get(nv_crtc); connector = &nv_connector->base; if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) { - if (nv_crtc->base.fb->depth > connector->display_info.bpc * 3) + if (nv_crtc->base.primary->fb->depth > connector->display_info.bpc * 3) mode = DITHERING_MODE_DYNAMIC2X2; } else { mode = nv_connector->dithering_mode; @@ -785,7 +786,8 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) if (update) { nv50_display_flip_stop(crtc); - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); + nv50_display_flip_next(crtc, crtc->primary->fb, + NULL, 1); } } @@ -956,7 +958,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc) nv50_display_flip_stop(crtc); - push = evo_wait(mast, 2); + push = evo_wait(mast, 6); if (push) { if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) { evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); @@ -1028,7 +1030,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) } nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true); - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); + nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); } static bool @@ -1042,7 +1044,7 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, static int nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb); + struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); struct nv50_head *head = nv50_head(crtc); int ret; @@ -1139,7 +1141,7 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, nv50_crtc_set_dither(nv_crtc, false); nv50_crtc_set_scale(nv_crtc, false); nv50_crtc_set_color_vibrance(nv_crtc, false); - nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, false); + nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); return 0; } @@ -1151,7 +1153,7 @@ nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); int ret; - if (!crtc->fb) { + if (!crtc->primary->fb) { NV_DEBUG(drm, "No FB bound\n"); return 0; } @@ -1161,8 +1163,8 @@ nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, return ret; nv50_display_flip_stop(crtc); - nv50_crtc_set_image(nv_crtc, crtc->fb, x, y, true); - nv50_display_flip_next(crtc, crtc->fb, NULL, 1); + nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, true); + nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); return 0; } @@ -1206,6 +1208,7 @@ static void nv50_crtc_disable(struct drm_crtc *crtc) { struct nv50_head *head = nv50_head(crtc); + evo_sync(crtc->dev); if (head->image) nouveau_bo_unpin(head->image); nouveau_bo_ref(NULL, &head->image); @@ -1699,10 +1702,9 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) } static void -nv50_hdmi_disconnect(struct drm_encoder *encoder) +nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) { struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); struct nv50_disp *disp = nv50_disp(encoder->dev); const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; @@ -1721,7 +1723,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct nv50_disp *disp = nv50_disp(dev); struct drm_encoder *partner; - int or = nv_encoder->or; + u32 mthd; nv_encoder->last_dpms = mode; @@ -1739,7 +1741,18 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) } } - nv_call(disp->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); + mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3; + mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2; + mthd |= nv_encoder->or; + + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { + nv_call(disp->core, NV50_DISP_SOR_PWR | mthd, 1); + mthd |= NV94_DISP_SOR_DP_PWR; + } else { + mthd |= NV50_DISP_SOR_PWR; + } + + nv_call(disp->core, mthd, (mode == DRM_MODE_DPMS_ON)); } static bool @@ -1763,33 +1776,36 @@ nv50_sor_mode_fixup(struct drm_encoder *encoder, } static void -nv50_sor_disconnect(struct drm_encoder *encoder) +nv50_sor_ctrl(struct nouveau_encoder *nv_encoder, u32 mask, u32 data) { - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); - struct nv50_mast *mast = nv50_mast(encoder->dev); - const int or = nv_encoder->or; - u32 *push; - - if (nv_encoder->crtc) { - nv50_crtc_prepare(nv_encoder->crtc); - - push = evo_wait(mast, 4); - if (push) { - if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) { - evo_mthd(push, 0x0600 + (or * 0x40), 1); - evo_data(push, 0x00000000); - } else { - evo_mthd(push, 0x0200 + (or * 0x20), 1); - evo_data(push, 0x00000000); - } - evo_kick(push, mast); + struct nv50_mast *mast = nv50_mast(nv_encoder->base.base.dev); + u32 temp = (nv_encoder->ctrl & ~mask) | (data & mask), *push; + if (temp != nv_encoder->ctrl && (push = evo_wait(mast, 2))) { + if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) { + evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1); + evo_data(push, (nv_encoder->ctrl = temp)); + } else { + evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1); + evo_data(push, (nv_encoder->ctrl = temp)); } - - nv50_hdmi_disconnect(encoder); + evo_kick(push, mast); } +} + +static void +nv50_sor_disconnect(struct drm_encoder *encoder) +{ + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; nv_encoder->crtc = NULL; + + if (nv_crtc) { + nv50_crtc_prepare(&nv_crtc->base); + nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0); + nv50_hdmi_disconnect(&nv_encoder->base.base, nv_crtc); + } } static void @@ -1809,12 +1825,14 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_connector *nv_connector; struct nvbios *bios = &drm->vbios; - u32 *push, lvds = 0; + u32 lvds = 0, mask, ctrl; u8 owner = 1 << nv_crtc->index; u8 proto = 0xf; u8 depth = 0x0; nv_connector = nouveau_encoder_connector_get(nv_encoder); + nv_encoder->crtc = encoder->crtc; + switch (nv_encoder->dcb->type) { case DCB_OUTPUT_TMDS: if (nv_encoder->dcb->sorconf.link & 1) { @@ -1826,7 +1844,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, proto = 0x2; } - nv50_hdmi_mode_set(encoder, mode); + nv50_hdmi_mode_set(&nv_encoder->base.base, mode); break; case DCB_OUTPUT_LVDS: proto = 0x0; @@ -1882,19 +1900,11 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, break; } - nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON); + nv50_sor_dpms(&nv_encoder->base.base, DRM_MODE_DPMS_ON); - push = evo_wait(nv50_mast(dev), 8); - if (push) { - if (nv50_vers(mast) < NVD0_DISP_CLASS) { - u32 ctrl = (depth << 16) | (proto << 8) | owner; - if (mode->flags & DRM_MODE_FLAG_NHSYNC) - ctrl |= 0x00001000; - if (mode->flags & DRM_MODE_FLAG_NVSYNC) - ctrl |= 0x00002000; - evo_mthd(push, 0x0600 + (nv_encoder->or * 0x040), 1); - evo_data(push, ctrl); - } else { + if (nv50_vers(mast) >= NVD0_DISP_CLASS) { + u32 *push = evo_wait(mast, 3); + if (push) { u32 magic = 0x31ec6000 | (nv_crtc->index << 25); u32 syncs = 0x00000001; @@ -1909,14 +1919,21 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); evo_data(push, syncs | (depth << 6)); evo_data(push, magic); - evo_mthd(push, 0x0200 + (nv_encoder->or * 0x020), 1); - evo_data(push, owner | (proto << 8)); + evo_kick(push, mast); } - evo_kick(push, mast); + ctrl = proto << 8; + mask = 0x00000f00; + } else { + ctrl = (depth << 16) | (proto << 8); + if (mode->flags & DRM_MODE_FLAG_NHSYNC) + ctrl |= 0x00001000; + if (mode->flags & DRM_MODE_FLAG_NVSYNC) + ctrl |= 0x00002000; + mask = 0x000f3f00; } - nv_encoder->crtc = encoder->crtc; + nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner); } static void @@ -2294,7 +2311,7 @@ nv50_display_create(struct drm_device *dev) continue; NV_WARN(drm, "%s has no encoders, removing\n", - drm_get_connector_name(connector)); + connector->name); connector->funcs->destroy(connector); } |
