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

Commit f58ddf95 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/nvif: assign internal class identifiers to sw classes



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 315a8b2e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -55,6 +55,10 @@ struct nvif_ioctl_new_v0 {
#define NVIF_IOCTL_NEW_V0_CONTROL                                            -1
#define NVIF_IOCTL_NEW_V0_PERFMON                                            -2
#define NVIF_IOCTL_NEW_V0_PERFDOM                                            -3
#define NVIF_IOCTL_NEW_V0_SW_NV04                                            -4
#define NVIF_IOCTL_NEW_V0_SW_NV10                                            -5
#define NVIF_IOCTL_NEW_V0_SW_NV50                                            -6
#define NVIF_IOCTL_NEW_V0_SW_GF100                                           -7
	__s32 oclass;
	__u8  data[];		/* class data (class.h) */
};
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ int nvkm_namedb_insert(struct nvkm_namedb *, u32 name, struct nvkm_object *,
void nvkm_namedb_remove(struct nvkm_handle *);

struct nvkm_handle *nvkm_namedb_get(struct nvkm_namedb *, u32);
struct nvkm_handle *nvkm_namedb_get_class(struct nvkm_namedb *, u16);
struct nvkm_handle *nvkm_namedb_get_class(struct nvkm_namedb *, s32);
struct nvkm_handle *nvkm_namedb_get_vinst(struct nvkm_namedb *, u64);
struct nvkm_handle *nvkm_namedb_get_cinst(struct nvkm_namedb *, u32);
void nvkm_namedb_put(struct nvkm_handle *);
+61 −15
Original line number Diff line number Diff line
@@ -74,23 +74,23 @@ nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret)
	return ret;
}

u16
s32
nouveau_abi16_swclass(struct nouveau_drm *drm)
{
	switch (drm->device.info.family) {
	case NV_DEVICE_INFO_V0_TNT:
		return 0x006e;
		return NVIF_IOCTL_NEW_V0_SW_NV04;
	case NV_DEVICE_INFO_V0_CELSIUS:
	case NV_DEVICE_INFO_V0_KELVIN:
	case NV_DEVICE_INFO_V0_RANKINE:
	case NV_DEVICE_INFO_V0_CURIE:
		return 0x016e;
		return NVIF_IOCTL_NEW_V0_SW_NV10;
	case NV_DEVICE_INFO_V0_TESLA:
		return 0x506e;
		return NVIF_IOCTL_NEW_V0_SW_NV50;
	case NV_DEVICE_INFO_V0_FERMI:
	case NV_DEVICE_INFO_V0_KEPLER:
	case NV_DEVICE_INFO_V0_MAXWELL:
		return 0x906e;
		return NVIF_IOCTL_NEW_V0_SW_GF100;
	}

	return 0x0000;
@@ -368,9 +368,10 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
	struct nouveau_abi16_chan *chan;
	struct nouveau_abi16_ntfy *ntfy;
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nvif_client *client;
	int ret;
	u32 sclass[32];
	s32 oclass = 0;
	int ret, i;

	if (unlikely(!abi16))
		return -ENOMEM;
@@ -379,17 +380,62 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
		return nouveau_abi16_put(abi16, -EINVAL);
	client = abi16->device.object.client;

	/* compatibility with userspace that assumes 506e for all chipsets */
	if (init->class == 0x506e) {
		init->class = nouveau_abi16_swclass(drm);
		if (init->class == 0x906e)
			return nouveau_abi16_put(abi16, 0);
	}

	chan = nouveau_abi16_chan(abi16, init->channel);
	if (!chan)
		return nouveau_abi16_put(abi16, -ENOENT);

	ret = nvif_object_sclass(&chan->chan->user, sclass, ARRAY_SIZE(sclass));
	if (ret < 0)
		return nouveau_abi16_put(abi16, ret);

	if ((init->class & 0x00ff) == 0x006e) {
		/* nvsw: compatibility with older 0x*6e class identifier */
		for (i = 0; !oclass && i < ret; i++) {
			switch (sclass[i]) {
			case NVIF_IOCTL_NEW_V0_SW_NV04:
			case NVIF_IOCTL_NEW_V0_SW_NV10:
			case NVIF_IOCTL_NEW_V0_SW_NV50:
			case NVIF_IOCTL_NEW_V0_SW_GF100:
				oclass = sclass[i];
				break;
			default:
				break;
			}
		}
	} else
	if ((init->class & 0x00ff) == 0x00b1) {
		/* msvld: compatibility with incorrect version exposure */
		for (i = 0; i < ret; i++) {
			if ((sclass[i] & 0x00ff) == 0x00b1) {
				oclass = sclass[i];
				break;
			}
		}
	} else
	if ((init->class & 0x00ff) == 0x00b2) { /* mspdec */
		/* mspdec: compatibility with incorrect version exposure */
		for (i = 0; i < ret; i++) {
			if ((sclass[i] & 0x00ff) == 0x00b2) {
				oclass = sclass[i];
				break;
			}
		}
	} else
	if ((init->class & 0x00ff) == 0x00b3) { /* msppp */
		/* msppp: compatibility with incorrect version exposure */
		for (i = 0; i < ret; i++) {
			if ((sclass[i] & 0x00ff) == 0x00b3) {
				oclass = sclass[i];
				break;
			}
		}
	} else {
		oclass = init->class;
	}

	if (!oclass)
		return nouveau_abi16_put(abi16, -EINVAL);

	ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL);
	if (!ntfy)
		return nouveau_abi16_put(abi16, -ENOMEM);
@@ -397,7 +443,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	list_add(&ntfy->head, &chan->notifiers);

	client->route = NVDRM_OBJECT_ABI16;
	ret = nvif_object_init(&chan->chan->user, init->handle, init->class,
	ret = nvif_object_init(&chan->chan->user, init->handle, oclass,
			       NULL, 0, &ntfy->object);
	client->route = NVDRM_OBJECT_NVIF;

+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ struct nouveau_drm;
struct nouveau_abi16 *nouveau_abi16_get(struct drm_file *, struct drm_device *);
int  nouveau_abi16_put(struct nouveau_abi16 *, int);
void nouveau_abi16_fini(struct nouveau_abi16 *);
u16  nouveau_abi16_swclass(struct nouveau_drm *);
s32  nouveau_abi16_swclass(struct nouveau_drm *);

#define NOUVEAU_GEM_DOMAIN_VRAM      (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART      (1 << 2)
+3 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <nvif/os.h>
#include <nvif/class.h>
#include <nvif/ioctl.h>

/*XXX*/
#include <core/client.h>
@@ -363,7 +364,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)

	/* allocate software object class (used for fences on <= nv05) */
	if (device->info.family < NV_DEVICE_INFO_V0_CELSIUS) {
		ret = nvif_object_init(&chan->user, 0x006e, 0x006e,
		ret = nvif_object_init(&chan->user, 0x006e,
				       NVIF_IOCTL_NEW_V0_SW_NV04,
				       NULL, 0, &chan->nvsw);
		if (ret)
			return ret;
Loading