drm/nouveau/disp: expose page flip event class

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
Ben Skeggs 2022-06-01 20:46:39 +10:00
parent 773eb04d14
commit 801bc8584e
7 changed files with 42 additions and 51 deletions

View file

@ -1081,10 +1081,10 @@ nv04_finish_page_flip(struct nouveau_channel *chan,
}
int
nv04_flip_complete(struct nvif_notify *notify)
nv04_flip_complete(struct nvif_event *event, void *argv, u32 argc)
{
struct nouveau_cli *cli = (void *)notify->object->client;
struct nouveau_drm *drm = cli->drm;
struct nv04_display *disp = container_of(event, typeof(*disp), flip);
struct nouveau_drm *drm = disp->drm;
struct nouveau_channel *chan = drm->channel;
struct nv04_page_flip_state state;
@ -1095,7 +1095,7 @@ nv04_flip_complete(struct nvif_notify *notify)
state.bpp / 8);
}
return NVIF_NOTIFY_KEEP;
return NVIF_EVENT_KEEP;
}
static int

View file

@ -61,7 +61,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend)
struct drm_crtc *crtc;
/* Disable flip completion events. */
nvif_notify_put(&disp->flip);
nvif_event_block(&disp->flip);
/* Disable vblank interrupts. */
NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
@ -121,7 +121,7 @@ nv04_display_init(struct drm_device *dev, bool resume, bool runtime)
encoder->enc_save(&encoder->base.base);
/* Enable flip completion events. */
nvif_notify_get(&disp->flip);
nvif_event_allow(&disp->flip);
if (!resume)
return 0;
@ -202,7 +202,7 @@ nv04_display_destroy(struct drm_device *dev)
nouveau_hw_save_vga_fonts(dev, 0);
nvif_notify_dtor(&disp->flip);
nvif_event_dtor(&disp->flip);
nouveau_display(dev)->priv = NULL;
vfree(disp);
@ -227,6 +227,8 @@ nv04_display_create(struct drm_device *dev)
if (!disp)
return -ENOMEM;
disp->drm = drm;
nvif_object_map(&drm->client.device.object, NULL, 0);
nouveau_display(dev)->priv = disp;
@ -239,9 +241,10 @@ nv04_display_create(struct drm_device *dev)
/* Request page flip completion event. */
if (drm->channel) {
nvif_notify_ctor(&drm->channel->nvsw, "kmsFlip", nv04_flip_complete,
false, NV04_NVSW_NTFY_UEVENT,
NULL, 0, 0, &disp->flip);
ret = nvif_event_ctor(&drm->channel->nvsw, "kmsFlip", 0, nv04_flip_complete,
true, NULL, 0, &disp->flip);
if (ret)
return ret;
}
nouveau_hw_save_vga_fonts(dev, 1);

View file

@ -6,6 +6,8 @@
#include "nouveau_display.h"
#include <nvif/event.h>
struct nouveau_encoder;
enum nv04_fp_display_regs {
@ -84,7 +86,8 @@ struct nv04_display {
uint32_t saved_vga_font[4][16384];
uint32_t dac_users[4];
struct nouveau_bo *image[2];
struct nvif_notify flip;
struct nvif_event flip;
struct nouveau_drm *drm;
};
static inline struct nv04_display *
@ -179,5 +182,5 @@ nouveau_bios_run_init_table(struct drm_device *dev, u16 table,
);
}
int nv04_flip_complete(struct nvif_notify *);
int nv04_flip_complete(struct nvif_event *, void *, u32);
#endif

View file

@ -2,7 +2,10 @@
#ifndef __NVIF_IF0004_H__
#define __NVIF_IF0004_H__
#define NV04_NVSW_NTFY_UEVENT 0x00
union nv04_nvsw_event_args {
struct nv04_nvsw_event_vn {
} vn;
};
#define NV04_NVSW_GET_REF 0x00

View file

@ -23,7 +23,6 @@
*/
#include "chan.h"
#include <core/notify.h>
#include <engine/fifo.h>
#include <nvif/event.h>
@ -36,7 +35,7 @@ nvkm_sw_chan_mthd(struct nvkm_sw_chan *chan, int subc, u32 mthd, u32 data)
case 0x0000:
return true;
case 0x0500:
nvkm_event_send(&chan->event, 1, 0, NULL, 0);
nvkm_event_send(&chan->event, NVKM_SW_CHAN_EVENT_PAGE_FLIP, 0, NULL, 0);
return true;
default:
if (chan->func->mthd)
@ -46,27 +45,8 @@ nvkm_sw_chan_mthd(struct nvkm_sw_chan *chan, int subc, u32 mthd, u32 data)
return false;
}
static int
nvkm_sw_chan_event_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
union {
struct nvif_notify_uevent_req none;
} *req = data;
int ret = -ENOSYS;
if (!(ret = nvif_unvers(ret, &data, &size, req->none))) {
notify->size = sizeof(struct nvif_notify_uevent_rep);
notify->types = 1;
notify->index = 0;
}
return ret;
}
static const struct nvkm_event_func
nvkm_sw_chan_event = {
.ctor = nvkm_sw_chan_event_ctor,
};
static void *

View file

@ -14,6 +14,7 @@ struct nvkm_sw_chan {
struct nvkm_fifo_chan *fifo;
struct list_head head;
#define NVKM_SW_CHAN_EVENT_PAGE_FLIP BIT(0)
struct nvkm_event event;
};

View file

@ -27,33 +27,34 @@
#include <nvif/if0004.h>
static int
nvkm_nvsw_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
nvkm_nvsw_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_uevent *uevent)
{
struct nvkm_nvsw *nvsw = nvkm_nvsw(object);
if (nvsw->func->mthd)
return nvsw->func->mthd(nvsw, mthd, data, size);
return -ENODEV;
union nv04_nvsw_event_args *args = argv;
if (!uevent)
return 0;
if (argc != sizeof(args->vn))
return -ENOSYS;
return nvkm_uevent_add(uevent, &nvkm_nvsw(object)->chan->event, 0,
NVKM_SW_CHAN_EVENT_PAGE_FLIP, NULL);
}
static int
nvkm_nvsw_ntfy_(struct nvkm_object *object, u32 mthd,
struct nvkm_event **pevent)
nvkm_nvsw_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
struct nvkm_nvsw *nvsw = nvkm_nvsw(object);
switch (mthd) {
case NV04_NVSW_NTFY_UEVENT:
*pevent = &nvsw->chan->event;
return 0;
default:
break;
}
return -EINVAL;
if (nvsw->func->mthd)
return nvsw->func->mthd(nvsw, mthd, data, size);
return -ENODEV;
}
static const struct nvkm_object_func
nvkm_nvsw_ = {
.mthd = nvkm_nvsw_mthd_,
.ntfy = nvkm_nvsw_ntfy_,
.mthd = nvkm_nvsw_mthd,
.uevent = nvkm_nvsw_uevent,
};
int