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

Commit 41a63406 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/nvif: return min/max versions for supported object classes



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f58ddf95
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -40,7 +40,11 @@ struct nvif_ioctl_sclass_v0 {
	__u8  version;
	__u8  count;
	__u8  pad02[6];
	__s32 oclass[];
	struct nvif_ioctl_sclass_oclass_v0 {
		__s32 oclass;
		__s16 minver;
		__s16 maxver;
	} oclass[];
};

struct nvif_ioctl_new_v0 {
+8 −1
Original line number Diff line number Diff line
@@ -3,6 +3,12 @@

#include <nvif/os.h>

struct nvif_sclass {
	s32 oclass;
	int minver;
	int maxver;
};

struct nvif_object {
	struct nvif_client *client;
	u32 handle;
@@ -18,7 +24,8 @@ int nvif_object_init(struct nvif_object *, u32 handle, s32 oclass, void *, u32,
		      struct nvif_object *);
void nvif_object_fini(struct nvif_object *);
int  nvif_object_ioctl(struct nvif_object *, void *, u32, void **);
int  nvif_object_sclass(struct nvif_object *, s32 *, int);
int  nvif_object_sclass_get(struct nvif_object *, struct nvif_sclass **);
void nvif_object_sclass_put(struct nvif_sclass **);
u32  nvif_object_rd(struct nvif_object *, int, u64);
void nvif_object_wr(struct nvif_object *, int, u64, u32);
int  nvif_object_mthd(struct nvif_object *, u32, void *, u32);
+1 −1
Original line number Diff line number Diff line
@@ -47,5 +47,5 @@ void _nvkm_parent_dtor(struct nvkm_object *);
int nvkm_parent_sclass(struct nvkm_object *, s32 handle,
		       struct nvkm_object **pengine,
		       struct nvkm_oclass **poclass);
int nvkm_parent_lclass(struct nvkm_object *, s32 *, int);
int nvkm_parent_lclass(struct nvkm_object *, void *, int);
#endif
+11 −10
Original line number Diff line number Diff line
@@ -369,7 +369,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	struct nouveau_abi16_chan *chan;
	struct nouveau_abi16_ntfy *ntfy;
	struct nvif_client *client;
	u32 sclass[32];
	struct nvif_sclass *sclass;
	s32 oclass = 0;
	int ret, i;

@@ -384,19 +384,19 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	if (!chan)
		return nouveau_abi16_put(abi16, -ENOENT);

	ret = nvif_object_sclass(&chan->chan->user, sclass, ARRAY_SIZE(sclass));
	ret = nvif_object_sclass_get(&chan->chan->user, &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]) {
			switch (sclass[i].oclass) {
			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];
				oclass = sclass[i].oclass;
				break;
			default:
				break;
@@ -406,8 +406,8 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	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];
			if ((sclass[i].oclass & 0x00ff) == 0x00b1) {
				oclass = sclass[i].oclass;
				break;
			}
		}
@@ -415,8 +415,8 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	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];
			if ((sclass[i].oclass & 0x00ff) == 0x00b2) {
				oclass = sclass[i].oclass;
				break;
			}
		}
@@ -424,8 +424,8 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
	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];
			if ((sclass[i].oclass & 0x00ff) == 0x00b3) {
				oclass = sclass[i].oclass;
				break;
			}
		}
@@ -433,6 +433,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
		oclass = init->class;
	}

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

+6 −5
Original line number Diff line number Diff line
@@ -152,9 +152,9 @@ static void
nouveau_accel_init(struct nouveau_drm *drm)
{
	struct nvif_device *device = &drm->device;
	struct nvif_sclass *sclass;
	u32 arg0, arg1;
	s32 sclass[16];
	int ret, i;
	int ret, i, n;

	if (nouveau_noaccel)
		return;
@@ -163,12 +163,12 @@ nouveau_accel_init(struct nouveau_drm *drm)
	/*XXX: this is crap, but the fence/channel stuff is a little
	 *     backwards in some places.  this will be fixed.
	 */
	ret = nvif_object_sclass(&device->object, sclass, ARRAY_SIZE(sclass));
	ret = n = nvif_object_sclass_get(&device->object, &sclass);
	if (ret < 0)
		return;

	for (ret = -ENOSYS, i = 0; ret && i < ARRAY_SIZE(sclass); i++) {
		switch (sclass[i]) {
	for (ret = -ENOSYS, i = 0; i < n; i++) {
		switch (sclass[i].oclass) {
		case NV03_CHANNEL_DMA:
			ret = nv04_fence_create(drm);
			break;
@@ -195,6 +195,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
		}
	}

	nvif_object_sclass_put(&sclass);
	if (ret) {
		NV_ERROR(drm, "failed to initialise sync subsystem, %d\n", ret);
		nouveau_accel_fini(drm);
Loading