Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 898a2b32 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/sw: turn flip completion into an event



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent cd459e77
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -584,6 +584,8 @@ struct nv50_disp_overlay_v0 {
 * software
 ******************************************************************************/

#define NVSW_NTFY_UEVENT                                                   0x00

#define NV04_NVSW_GET_REF                                                  0x00

struct nv04_nvsw_get_ref_v0 {
+0 −22
Original line number Diff line number Diff line
#ifndef __NVKM_SW_H__
#define __NVKM_SW_H__
#include <core/engctx.h>

struct nvkm_sw_chan {
	struct nvkm_engctx base;

	int (*flip)(void *);
	void *flip_data;
};

#define nvkm_sw_context_create(p,e,c,d)                               \
	nvkm_engctx_create((p), (e), (c), (p), 0, 0, 0, (d))
#define nvkm_sw_context_destroy(d)                                    \
	nvkm_engctx_destroy(&(d)->base)
#define nvkm_sw_context_init(d)                                       \
	nvkm_engctx_init(&(d)->base)
#define nvkm_sw_context_fini(d,s)                                     \
	nvkm_engctx_fini(&(d)->base, (s))

#define _nvkm_sw_context_dtor _nvkm_engctx_dtor
#define _nvkm_sw_context_init _nvkm_engctx_init
#define _nvkm_sw_context_fini _nvkm_engctx_fini

#include <core/engine.h>

struct nvkm_sw {
+0 −5
Original line number Diff line number Diff line
@@ -293,7 +293,6 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
	struct nvif_device *device = chan->device;
	struct nouveau_cli *cli = (void *)chan->user.client;
	struct nvkm_mmu *mmu = nvxx_mmu(device);
	struct nvkm_sw_chan *swch;
	struct nv_dma_v0 args = {};
	int ret, i;

@@ -382,10 +381,6 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
		if (ret)
			return ret;

		swch = (void *)nvxx_object(&chan->nvsw)->parent;
		swch->flip = nouveau_flip_complete;
		swch->flip_data = chan;

		ret = RING_SPACE(chan, 2);
		if (ret)
			return ret;
+11 −4
Original line number Diff line number Diff line
@@ -358,6 +358,7 @@ int
nouveau_display_init(struct drm_device *dev)
{
	struct nouveau_display *disp = nouveau_display(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct drm_connector *connector;
	int ret;

@@ -374,6 +375,8 @@ nouveau_display_init(struct drm_device *dev)
		nvif_notify_get(&conn->hpd);
	}

	/* enable flip completion events */
	nvif_notify_get(&drm->flip);
	return ret;
}

@@ -381,6 +384,7 @@ void
nouveau_display_fini(struct drm_device *dev)
{
	struct nouveau_display *disp = nouveau_display(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct drm_connector *connector;
	int head;

@@ -388,6 +392,9 @@ nouveau_display_fini(struct drm_device *dev)
	for (head = 0; head < dev->mode_config.num_crtc; head++)
		drm_vblank_off(dev, head);

	/* disable flip completion events */
	nvif_notify_put(&drm->flip);

	/* disable hotplug interrupts */
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		struct nouveau_connector *conn = nouveau_connector(connector);
@@ -847,10 +854,10 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
}

int
nouveau_flip_complete(void *data)
nouveau_flip_complete(struct nvif_notify *notify)
{
	struct nouveau_channel *chan = data;
	struct nouveau_drm *drm = chan->drm;
	struct nouveau_drm *drm = container_of(notify, typeof(*drm), flip);
	struct nouveau_channel *chan = drm->channel;
	struct nouveau_page_flip_state state;

	if (!nouveau_finish_page_flip(chan, &state)) {
@@ -861,7 +868,7 @@ nouveau_flip_complete(void *data)
		}
	}

	return 0;
	return NVIF_NOTIFY_KEEP;
}

int
+11 −4
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ nouveau_cli_destroy(struct nouveau_cli *cli)
static void
nouveau_accel_fini(struct nouveau_drm *drm)
{
	nvif_notify_fini(&drm->flip);
	nouveau_channel_del(&drm->channel);
	nvif_object_fini(&drm->ntfy);
	nvkm_gpuobj_del(&drm->notify);
@@ -240,7 +241,6 @@ nouveau_accel_init(struct nouveau_drm *drm)
	ret = nvif_object_init(&drm->channel->user, NVDRM_NVSW,
			       nouveau_abi16_swclass(drm), NULL, 0, &drm->nvsw);
	if (ret == 0) {
		struct nvkm_sw_chan *swch;
		ret = RING_SPACE(drm->channel, 2);
		if (ret == 0) {
			if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
@@ -252,9 +252,16 @@ nouveau_accel_init(struct nouveau_drm *drm)
				OUT_RING  (drm->channel, 0x001f0000);
			}
		}
		swch = (void *)nvxx_object(&drm->nvsw)->parent;
		swch->flip = nouveau_flip_complete;
		swch->flip_data = drm->channel;

		ret = nvif_notify_init(&drm->nvsw, nouveau_flip_complete,
				       false, NVSW_NTFY_UEVENT, NULL, 0, 0,
				       &drm->flip);
		if (ret == 0)
			ret = nvif_notify_get(&drm->flip);
		if (ret) {
			nouveau_accel_fini(drm);
			return;
		}
	}

	if (ret) {
Loading