drm/nouveau/disp: expose head event class
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:46:38 +0000 (20:46 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:27 +0000 (10:44 +1000)
Also fixes vblank interrupts being left enabled when they're not meant
to be as a result of races/bugs in previous event handling code.

v2:
- use ?: (lyude)

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
drivers/gpu/drm/nouveau/dispnv04/crtc.c
drivers/gpu/drm/nouveau/dispnv50/head.c
drivers/gpu/drm/nouveau/include/nvif/cl0046.h
drivers/gpu/drm/nouveau/include/nvif/event.h
drivers/gpu/drm/nouveau/include/nvif/head.h
drivers/gpu/drm/nouveau/include/nvif/if0013.h
drivers/gpu/drm/nouveau/nouveau_crtc.h
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nvif/head.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c

index f35c256..80b0b5c 100644 (file)
@@ -761,7 +761,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
        nouveau_bo_unmap(nv_crtc->cursor.nvbo);
        nouveau_bo_unpin(nv_crtc->cursor.nvbo);
        nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
-       nvif_notify_dtor(&nv_crtc->vblank);
+       nvif_event_dtor(&nv_crtc->vblank);
        nvif_head_dtor(&nv_crtc->head);
        kfree(nv_crtc);
 }
@@ -1280,13 +1280,13 @@ static const struct drm_plane_funcs nv04_primary_plane_funcs = {
        DRM_PLANE_NON_ATOMIC_FUNCS,
 };
 
-static int nv04_crtc_vblank_handler(struct nvif_notify *notify)
+static int
+nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc)
 {
-       struct nouveau_crtc *nv_crtc =
-               container_of(notify, struct nouveau_crtc, vblank);
+       struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank);
 
        drm_crtc_handle_vblank(&nv_crtc->base);
-       return NVIF_NOTIFY_KEEP;
+       return NVIF_EVENT_KEEP;
 }
 
 int
@@ -1346,14 +1346,6 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
        if (ret)
                return ret;
 
-       ret = nvif_notify_ctor(&disp->disp.object, "kmsVbl", nv04_crtc_vblank_handler,
-                              false, NV04_DISP_NTFY_VBLANK,
-                              &(struct nvif_notify_head_req_v0) {
-                                   .head = nv_crtc->index,
-                              },
-                              sizeof(struct nvif_notify_head_req_v0),
-                              sizeof(struct nvif_notify_head_rep_v0),
-                              &nv_crtc->vblank);
-
-       return ret;
+       return nvif_head_vblank_event_ctor(&nv_crtc->head, "kmsVbl", nv04_crtc_vblank_handler,
+                                          false, &nv_crtc->vblank);
 }
index 8ac3474..f006e56 100644 (file)
@@ -517,7 +517,7 @@ nv50_head_destroy(struct drm_crtc *crtc)
 {
        struct nv50_head *head = nv50_head(crtc);
 
-       nvif_notify_dtor(&head->base.vblank);
+       nvif_event_dtor(&head->base.vblank);
        nvif_head_dtor(&head->base.head);
        nv50_lut_fini(&head->olut);
        drm_crtc_cleanup(crtc);
@@ -555,15 +555,15 @@ nvd9_head_func = {
        .late_register = nv50_head_late_register,
 };
 
-static int nv50_head_vblank_handler(struct nvif_notify *notify)
+static int
+nv50_head_vblank_handler(struct nvif_event *event, void *repv, u32 repc)
 {
-       struct nouveau_crtc *nv_crtc =
-               container_of(notify, struct nouveau_crtc, vblank);
+       struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank);
 
        if (drm_crtc_handle_vblank(&nv_crtc->base))
                nv50_crc_handle_vblank(nv50_head(&nv_crtc->base));
 
-       return NVIF_NOTIFY_KEEP;
+       return NVIF_EVENT_KEEP;
 }
 
 struct nv50_head *
@@ -629,14 +629,8 @@ nv50_head_create(struct drm_device *dev, int index)
        if (ret)
                return ERR_PTR(ret);
 
-       ret = nvif_notify_ctor(&disp->disp->object, "kmsVbl", nv50_head_vblank_handler,
-                              false, NV04_DISP_NTFY_VBLANK,
-                              &(struct nvif_notify_head_req_v0) {
-                                   .head = nv_crtc->index,
-                              },
-                              sizeof(struct nvif_notify_head_req_v0),
-                              sizeof(struct nvif_notify_head_rep_v0),
-                              &nv_crtc->vblank);
+       ret = nvif_head_vblank_event_ctor(&head->base.head, "kmsVbl", nv50_head_vblank_handler,
+                                         false, &nv_crtc->vblank);
        if (ret)
                return ERR_PTR(ret);
 
index b3ac930..eca7c39 100644 (file)
@@ -2,6 +2,5 @@
 #ifndef __NVIF_CL0046_H__
 #define __NVIF_CL0046_H__
 
-#define NV04_DISP_NTFY_VBLANK                                              0x00
 #define NV04_DISP_NTFY_CONN                                                0x01
 #endif
index 7521196..6799504 100644 (file)
@@ -52,17 +52,6 @@ struct nvif_notify_rep_v0 {
        __u8  data[];   /* reply data (below) */
 };
 
-struct nvif_notify_head_req_v0 {
-       /* nvif_notify_req ... */
-       __u8  version;
-       __u8  head;
-       __u8  pad02[6];
-};
-
-struct nvif_notify_head_rep_v0 {
-       /* nvif_notify_rep ... */
-};
-
 struct nvif_notify_conn_req_v0 {
        /* nvif_notify_req ... */
        __u8  version;
index 09170c7..3ec3699 100644 (file)
@@ -2,6 +2,7 @@
 #ifndef __NVIF_HEAD_H__
 #define __NVIF_HEAD_H__
 #include <nvif/object.h>
+#include <nvif/event.h>
 struct nvif_disp;
 
 struct nvif_head {
@@ -10,4 +11,13 @@ struct nvif_head {
 
 int nvif_head_ctor(struct nvif_disp *, const char *name, int id, struct nvif_head *);
 void nvif_head_dtor(struct nvif_head *);
+
+static inline int
+nvif_head_id(struct nvif_head *head)
+{
+       return head->object.handle;
+}
+
+int nvif_head_vblank_event_ctor(struct nvif_head *, const char *name, nvif_event_func, bool wait,
+                               struct nvif_event *);
 #endif
index 4bd9507..6756c74 100644 (file)
@@ -10,6 +10,11 @@ union nvif_head_args {
        } v0;
 };
 
+union nvif_head_event_args {
+       struct nvif_head_event_vn {
+       } vn;
+};
+
 #define NVIF_HEAD_V0_SCANOUTPOS 0x00
 
 union nvif_head_scanoutpos_args {
index e85e74f..c717f66 100644 (file)
 #include <drm/drm_crtc.h>
 
 #include <nvif/head.h>
-#include <nvif/notify.h>
+#include <nvif/event.h>
 
 struct nouveau_crtc {
        struct drm_crtc base;
 
        struct nvif_head head;
        int index;
-       struct nvif_notify vblank;
+       struct nvif_event vblank;
 
        uint32_t dpms_saved_fp_control;
        uint32_t fp_users;
index 2034346..e88845a 100644 (file)
@@ -52,7 +52,7 @@ nouveau_display_vblank_enable(struct drm_crtc *crtc)
        struct nouveau_crtc *nv_crtc;
 
        nv_crtc = nouveau_crtc(crtc);
-       nvif_notify_get(&nv_crtc->vblank);
+       nvif_event_allow(&nv_crtc->vblank);
 
        return 0;
 }
@@ -63,7 +63,7 @@ nouveau_display_vblank_disable(struct drm_crtc *crtc)
        struct nouveau_crtc *nv_crtc;
 
        nv_crtc = nouveau_crtc(crtc);
-       nvif_notify_put(&nv_crtc->vblank);
+       nvif_event_block(&nv_crtc->vblank);
 }
 
 static inline int
index 01deba4..f00e01d 100644 (file)
 #include <nvif/class.h>
 #include <nvif/if0013.h>
 
+int
+nvif_head_vblank_event_ctor(struct nvif_head *head, const char *name, nvif_event_func func,
+                           bool wait, struct nvif_event *event)
+{
+       int ret = nvif_event_ctor(&head->object, name ?: "nvifHeadVBlank", nvif_head_id(head),
+                                 func, wait, NULL, 0, event);
+       NVIF_ERRON(ret, &head->object, "[NEW EVENT:VBLANK]");
+       return ret;
+}
+
 void
 nvif_head_dtor(struct nvif_head *head)
 {
index 7d28613..3991959 100644 (file)
@@ -57,32 +57,8 @@ nvkm_disp_vblank_init(struct nvkm_event *event, int type, int id)
                head->func->vblank_get(head);
 }
 
-static int
-nvkm_disp_vblank_ctor(struct nvkm_object *object, void *data, u32 size,
-                     struct nvkm_notify *notify)
-{
-       struct nvkm_disp *disp =
-               container_of(notify->event, typeof(*disp), vblank);
-       union {
-               struct nvif_notify_head_req_v0 v0;
-       } *req = data;
-       int ret = -ENOSYS;
-
-       if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
-               notify->size = sizeof(struct nvif_notify_head_rep_v0);
-               if (ret = -ENXIO, req->v0.head <= disp->vblank.index_nr) {
-                       notify->types = 1;
-                       notify->index = req->v0.head;
-                       return 0;
-               }
-       }
-
-       return ret;
-}
-
 static const struct nvkm_event_func
 nvkm_disp_vblank_func = {
-       .ctor = nvkm_disp_vblank_ctor,
        .init = nvkm_disp_vblank_init,
        .fini = nvkm_disp_vblank_fini,
 };
@@ -132,9 +108,6 @@ nvkm_disp_ntfy(struct nvkm_object *object, u32 type, struct nvkm_event **event)
 {
        struct nvkm_disp *disp = nvkm_disp(object->engine);
        switch (type) {
-       case NV04_DISP_NTFY_VBLANK:
-               *event = &disp->vblank;
-               return 0;
        case NV04_DISP_NTFY_CONN:
                *event = &disp->hpd;
                return 0;
index 5f3c4b7..f072cec 100644 (file)
  */
 #define nvkm_uhead(p) container_of((p), struct nvkm_head, object)
 #include "head.h"
+#include <core/event.h>
 
 #include <nvif/if0013.h>
 
+#include <nvif/event.h>
+
+static int
+nvkm_uhead_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
+{
+       struct nvkm_head *head = nvkm_uhead(object);
+       union nvif_head_event_args *args = argv;
+
+       if (!uevent)
+               return 0;
+       if (argc != sizeof(args->vn))
+               return -ENOSYS;
+
+       return nvkm_uevent_add(uevent, &head->disp->vblank, head->id,
+                              NVKM_DISP_HEAD_EVENT_VBLANK, NULL);
+}
+
 static int
 nvkm_uhead_mthd_scanoutpos(struct nvkm_head *head, void *argv, u32 argc)
 {
@@ -81,6 +99,7 @@ static const struct nvkm_object_func
 nvkm_uhead = {
        .dtor = nvkm_uhead_dtor,
        .mthd = nvkm_uhead_mthd,
+       .uevent = nvkm_uhead_uevent,
 };
 
 int