0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <nvif/fifo.h>
0023
0024 static int
0025 nvif_fifo_runlists(struct nvif_device *device)
0026 {
0027 struct nvif_object *object = &device->object;
0028 struct {
0029 struct nv_device_info_v1 m;
0030 struct {
0031 struct nv_device_info_v1_data runlists;
0032 struct nv_device_info_v1_data runlist[64];
0033 } v;
0034 } *a;
0035 int ret, i;
0036
0037 if (device->runlist)
0038 return 0;
0039
0040 if (!(a = kmalloc(sizeof(*a), GFP_KERNEL)))
0041 return -ENOMEM;
0042 a->m.version = 1;
0043 a->m.count = sizeof(a->v) / sizeof(a->v.runlists);
0044 a->v.runlists.mthd = NV_DEVICE_HOST_RUNLISTS;
0045 for (i = 0; i < ARRAY_SIZE(a->v.runlist); i++) {
0046 a->v.runlist[i].mthd = NV_DEVICE_HOST_RUNLIST_ENGINES;
0047 a->v.runlist[i].data = i;
0048 }
0049
0050 ret = nvif_object_mthd(object, NV_DEVICE_V0_INFO, a, sizeof(*a));
0051 if (ret)
0052 goto done;
0053
0054 device->runlists = fls64(a->v.runlists.data);
0055 device->runlist = kcalloc(device->runlists, sizeof(*device->runlist),
0056 GFP_KERNEL);
0057 if (!device->runlist) {
0058 ret = -ENOMEM;
0059 goto done;
0060 }
0061
0062 for (i = 0; i < device->runlists; i++) {
0063 if (a->v.runlist[i].mthd != NV_DEVICE_INFO_INVALID)
0064 device->runlist[i].engines = a->v.runlist[i].data;
0065 }
0066
0067 done:
0068 kfree(a);
0069 return ret;
0070 }
0071
0072 u64
0073 nvif_fifo_runlist(struct nvif_device *device, u64 engine)
0074 {
0075 u64 runm = 0;
0076 int ret, i;
0077
0078 if ((ret = nvif_fifo_runlists(device)))
0079 return runm;
0080
0081 for (i = 0; i < device->runlists; i++) {
0082 if (device->runlist[i].engines & engine)
0083 runm |= BIT_ULL(i);
0084 }
0085
0086 return runm;
0087 }