drm/nouveau: bring back blit subchannel for pre nv50 GPUs
authorKarol Herbst <kherbst@redhat.com>
Fri, 26 May 2023 09:10:52 +0000 (11:10 +0200)
committerKarol Herbst <kherbst@redhat.com>
Wed, 12 Jul 2023 20:38:41 +0000 (22:38 +0200)
1ba6113a90a0 removed a lot of the kernel GPU channel, but method 0x128
was important as otherwise the GPU spams us with `CACHE_ERROR` messages.

We use the blit subchannel inside our vblank handling, so we should keep
at least this part.

v2: Only do it for NV11+ GPUs

Closes: https://gitlab.freedesktop.org/drm/nouveau/-/issues/201
Fixes: 4a16dd9d18a0 ("drm/nouveau/kms: switch to drm fbdev helpers")
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230526091052.2169044-1-kherbst@redhat.com
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_chan.h
drivers/gpu/drm/nouveau/nouveau_drm.c

index e648ecd..3dfbc37 100644 (file)
@@ -90,6 +90,7 @@ nouveau_channel_del(struct nouveau_channel **pchan)
                if (cli)
                        nouveau_svmm_part(chan->vmm->svmm, chan->inst);
 
+               nvif_object_dtor(&chan->blit);
                nvif_object_dtor(&chan->nvsw);
                nvif_object_dtor(&chan->gart);
                nvif_object_dtor(&chan->vram);
index e06a8ff..bad7466 100644 (file)
@@ -53,6 +53,7 @@ struct nouveau_channel {
        u32 user_put;
 
        struct nvif_object user;
+       struct nvif_object blit;
 
        struct nvif_event kill;
        atomic_t killed;
index 7aac938..40fb9a8 100644 (file)
@@ -375,15 +375,29 @@ nouveau_accel_gr_init(struct nouveau_drm *drm)
                ret = nvif_object_ctor(&drm->channel->user, "drmNvsw",
                                       NVDRM_NVSW, nouveau_abi16_swclass(drm),
                                       NULL, 0, &drm->channel->nvsw);
+
+               if (ret == 0 && device->info.chipset >= 0x11) {
+                       ret = nvif_object_ctor(&drm->channel->user, "drmBlit",
+                                              0x005f, 0x009f,
+                                              NULL, 0, &drm->channel->blit);
+               }
+
                if (ret == 0) {
                        struct nvif_push *push = drm->channel->chan.push;
-                       ret = PUSH_WAIT(push, 2);
-                       if (ret == 0)
+                       ret = PUSH_WAIT(push, 8);
+                       if (ret == 0) {
+                               if (device->info.chipset >= 0x11) {
+                                       PUSH_NVSQ(push, NV05F, 0x0000, drm->channel->blit.handle);
+                                       PUSH_NVSQ(push, NV09F, 0x0120, 0,
+                                                              0x0124, 1,
+                                                              0x0128, 2);
+                               }
                                PUSH_NVSQ(push, NV_SW, 0x0000, drm->channel->nvsw.handle);
+                       }
                }
 
                if (ret) {
-                       NV_ERROR(drm, "failed to allocate sw class, %d\n", ret);
+                       NV_ERROR(drm, "failed to allocate sw or blit class, %d\n", ret);
                        nouveau_accel_gr_fini(drm);
                        return;
                }