Commit 93f43ed8 authored by Ben Skeggs's avatar Ben Skeggs Committed by Karol Herbst

ce/gf100: fix incorrect CE0 address calculation on some GPUs

The code which constructs the modules for each engine present on the GPU
passes -1 for 'instance' on non-instanced engines, which affects how the
name for a sub-device is generated.  This is then stored as 'instance 0'
in nvkm_subdev.inst, so code can potentially be shared with earlier GPUs
that only had a single instance of an engine.

However, GF100's CE constructor uses this value to calculate the address
of its falcon before it's translated, resulting in CE0 getting the wrong
address.

This slightly modifies the approach, always passing a valid instance for
engines that *can* have multiple copies, and having the code for earlier
GPUs explicitly ask for non-instanced name generation.

Bug: https://gitlab.freedesktop.org/drm/nouveau/-/issues/91

Fixes: 50551b15 ("drm/nouveau/ce: switch to instanced constructor")
Cc: <stable@vger.kernel.org> # v5.12+
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarKarol Herbst <kherbst@redhat.com>
Tested-by: default avatarKarol Herbst <kherbst@redhat.com>
Signed-off-by: default avatarKarol Herbst <kherbst@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211103011057.15344-1-skeggsb@gmail.com
parent 8244a3bc
...@@ -78,6 +78,6 @@ int ...@@ -78,6 +78,6 @@ int
gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_engine **pengine) struct nvkm_engine **pengine)
{ {
return nvkm_falcon_new_(&gt215_ce, device, type, inst, return nvkm_falcon_new_(&gt215_ce, device, type, -1,
(device->chipset != 0xaf), 0x104000, pengine); (device->chipset != 0xaf), 0x104000, pengine);
} }
...@@ -3147,8 +3147,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, ...@@ -3147,8 +3147,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \ WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \
for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \ for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \
if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \ if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \
int inst = (device->chip->ptr.inst == 1) ? -1 : (j); \ ret = device->chip->ptr.ctor(device, (type), (j), &device->ptr[j]); \
ret = device->chip->ptr.ctor(device, (type), inst, &device->ptr[j]); \
subdev = nvkm_device_subdev(device, (type), (j)); \ subdev = nvkm_device_subdev(device, (type), (j)); \
if (ret) { \ if (ret) { \
nvkm_subdev_del(&subdev); \ nvkm_subdev_del(&subdev); \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment