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

drm/nouveau/nvkm: add macros for subdev layout



Rather than having to add new engines / engine instances to multiple places,
define everything in include/nvkm/core/layout.h and use macros to generate
the required plumbing.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent efe2a9ec
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#define __NVKM_DEVICE_H__
#include <core/oclass.h>
#include <core/event.h>
enum nvkm_subdev_type;

#define nvkm_devidx nvkm_subdev_type

@@ -108,6 +109,11 @@ struct nvkm_device {
	struct nvkm_engine *vic;
	struct nvkm_engine *vp;

#define NVKM_LAYOUT_ONCE(type,data,ptr) data *ptr;
#define NVKM_LAYOUT_INST(type,data,ptr,cnt) data *ptr[cnt];
#include <core/layout.h>
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
	struct list_head subdev;
};

@@ -133,7 +139,15 @@ struct nvkm_device_quirk {

struct nvkm_device_chip {
	const char *name;

#define NVKM_LAYOUT_ONCE(type,data,ptr,...)                                                  \
	struct {                                                                             \
		u32 inst;                                                                    \
		int (*ctor)(struct nvkm_device *, enum nvkm_subdev_type, int inst, data **); \
	} ptr;
#define NVKM_LAYOUT_INST(A...) NVKM_LAYOUT_ONCE(A)
#include <core/layout.h>
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
	int (*acr     )(struct nvkm_device *, int idx, struct nvkm_acr **);
	int (*bar     )(struct nvkm_device *, int idx, struct nvkm_bar **);
	int (*bios    )(struct nvkm_device *, int idx, struct nvkm_bios **);
+1 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct nvkm_subdev {
	u32 debug;
	struct list_head head;

	void **pself;
	bool oneinit;
};

@@ -111,6 +112,7 @@ void nvkm_subdev_ctor_(const struct nvkm_subdev_func *, bool old, struct nvkm_de
#define nvkm_subdev_ctor_n(f,d,t,i,s) nvkm_subdev_ctor_((f), false, (d), (t), (i), (s))
#define nvkm_subdev_ctor__(_1,_2,_3,_4,_5,IMPL,...) IMPL
#define nvkm_subdev_ctor(A...) nvkm_subdev_ctor__(A, nvkm_subdev_ctor_n, nvkm_subdev_ctor_o)(A)
void nvkm_subdev_disable(struct nvkm_device *, enum nvkm_subdev_type, int inst);
void nvkm_subdev_del(struct nvkm_subdev **);
int  nvkm_subdev_preinit(struct nvkm_subdev *);
int  nvkm_subdev_init(struct nvkm_subdev *);
+18 −0
Original line number Diff line number Diff line
@@ -28,6 +28,11 @@

const char *
nvkm_subdev_type[NVKM_SUBDEV_NR] = {
#define NVKM_LAYOUT_ONCE(type,data,ptr,...) [type] = #ptr,
#define NVKM_LAYOUT_INST(A...) NVKM_LAYOUT_ONCE(A)
#include <core/layout.h>
#undef NVKM_LAYOUT_ONCE
#undef NVKM_LAYOUT_INST
	[NVKM_SUBDEV_ACR     ] = "acr",
	[NVKM_SUBDEV_BAR     ] = "bar",
	[NVKM_SUBDEV_VBIOS   ] = "bios",
@@ -207,6 +212,19 @@ nvkm_subdev_del(struct nvkm_subdev **psubdev)
	}
}

void
nvkm_subdev_disable(struct nvkm_device *device, enum nvkm_subdev_type type, int inst)
{
	struct nvkm_subdev *subdev;
	list_for_each_entry(subdev, &device->subdev, head) {
		if (subdev->type == type && subdev->inst == inst) {
			*subdev->pself = NULL;
			nvkm_subdev_del(&subdev);
			break;
		}
	}
}

void
nvkm_subdev_ctor_(const struct nvkm_subdev_func *func, bool old,
		 struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
+42 −0
Original line number Diff line number Diff line
@@ -3206,6 +3206,48 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
	}                                                                      \
	break
		switch (i) {
#define NVKM_LAYOUT_ONCE(type,data,ptr) case type:                                           \
	if (device->chip->ptr.inst && (subdev_mask & (BIT_ULL(type)))) {                     \
		WARN_ON(device->chip->ptr.inst != 0x00000001);                               \
		ret = device->chip->ptr.ctor(device, (type), -1, &device->ptr);              \
		subdev = nvkm_device_subdev(device, (type), 0);                              \
		if (ret) {                                                                   \
			nvkm_subdev_del(&subdev);                                            \
			device->ptr = NULL;                                                  \
			if (ret != -ENODEV) {                                                \
				nvdev_error(device, "%s ctor failed: %d\n",                  \
					    nvkm_subdev_type[(type)], ret);                  \
				goto done;                                                   \
			}                                                                    \
		} else {                                                                     \
			subdev->pself = (void **)&device->ptr;                               \
		}                                                                            \
	}                                                                                    \
	break;
#define NVKM_LAYOUT_INST(type,data,ptr,cnt) case type:                                       \
	WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1));             \
	for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) {            \
		if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) {    \
			int inst = (device->chip->ptr.inst == 1) ? -1 : (j);                 \
			ret = device->chip->ptr.ctor(device, (type), inst, &device->ptr[j]); \
			subdev = nvkm_device_subdev(device, (type), (j));                    \
			if (ret) {                                                           \
				nvkm_subdev_del(&subdev);                                    \
				device->ptr[j] = NULL;                                       \
				if (ret != -ENODEV) {                                        \
					nvdev_error(device, "%s%d ctor failed: %d\n",        \
						    nvkm_subdev_type[(type)], (j), ret);     \
					goto done;                                           \
				}                                                            \
			} else {                                                             \
				subdev->pself = (void **)&device->ptr[j];                    \
			}                                                                    \
		}                                                                            \
	}                                                                                    \
	break;
#include <core/layout.h>
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
		_(NVKM_SUBDEV_ACR     ,      acr);
		_(NVKM_SUBDEV_BAR     ,      bar);
		_(NVKM_SUBDEV_VBIOS   ,     bios);