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: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
Родитель
efe2a9eccd
Коммит
f483253f34
|
@ -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 **);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
|
@ -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 *);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче