xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/core/nouveau_nvkm_core_subdev.c (revision 798b8d11ecd8257a8e35c3396210f98abf3d9ade)
1 /*	$NetBSD: nouveau_nvkm_core_subdev.c,v 1.5 2021/12/19 11:34:44 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2012 Red Hat Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Ben Skeggs
25  */
26 #include <sys/cdefs.h>
27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_core_subdev.c,v 1.5 2021/12/19 11:34:44 riastradh Exp $");
28 
29 #include <core/subdev.h>
30 #include <core/device.h>
31 #include <core/option.h>
32 #include <subdev/mc.h>
33 
34 #include <linux/nbsd-namespace.h>
35 
36 static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR];
37 
38 const char *
39 nvkm_subdev_name[NVKM_SUBDEV_NR] = {
40 	[NVKM_SUBDEV_ACR     ] = "acr",
41 	[NVKM_SUBDEV_BAR     ] = "bar",
42 	[NVKM_SUBDEV_VBIOS   ] = "bios",
43 	[NVKM_SUBDEV_BUS     ] = "bus",
44 	[NVKM_SUBDEV_CLK     ] = "clk",
45 	[NVKM_SUBDEV_DEVINIT ] = "devinit",
46 	[NVKM_SUBDEV_FAULT   ] = "fault",
47 	[NVKM_SUBDEV_FB      ] = "fb",
48 	[NVKM_SUBDEV_FUSE    ] = "fuse",
49 	[NVKM_SUBDEV_GPIO    ] = "gpio",
50 	[NVKM_SUBDEV_GSP     ] = "gsp",
51 	[NVKM_SUBDEV_I2C     ] = "i2c",
52 	[NVKM_SUBDEV_IBUS    ] = "priv",
53 	[NVKM_SUBDEV_ICCSENSE] = "iccsense",
54 	[NVKM_SUBDEV_INSTMEM ] = "imem",
55 	[NVKM_SUBDEV_LTC     ] = "ltc",
56 	[NVKM_SUBDEV_MC      ] = "mc",
57 	[NVKM_SUBDEV_MMU     ] = "mmu",
58 	[NVKM_SUBDEV_MXM     ] = "mxm",
59 	[NVKM_SUBDEV_PCI     ] = "pci",
60 	[NVKM_SUBDEV_PMU     ] = "pmu",
61 	[NVKM_SUBDEV_THERM   ] = "therm",
62 	[NVKM_SUBDEV_TIMER   ] = "tmr",
63 	[NVKM_SUBDEV_TOP     ] = "top",
64 	[NVKM_SUBDEV_VOLT    ] = "volt",
65 	[NVKM_ENGINE_BSP     ] = "bsp",
66 	[NVKM_ENGINE_CE0     ] = "ce0",
67 	[NVKM_ENGINE_CE1     ] = "ce1",
68 	[NVKM_ENGINE_CE2     ] = "ce2",
69 	[NVKM_ENGINE_CE3     ] = "ce3",
70 	[NVKM_ENGINE_CE4     ] = "ce4",
71 	[NVKM_ENGINE_CE5     ] = "ce5",
72 	[NVKM_ENGINE_CE6     ] = "ce6",
73 	[NVKM_ENGINE_CE7     ] = "ce7",
74 	[NVKM_ENGINE_CE8     ] = "ce8",
75 	[NVKM_ENGINE_CIPHER  ] = "cipher",
76 	[NVKM_ENGINE_DISP    ] = "disp",
77 	[NVKM_ENGINE_DMAOBJ  ] = "dma",
78 	[NVKM_ENGINE_FIFO    ] = "fifo",
79 	[NVKM_ENGINE_GR      ] = "gr",
80 	[NVKM_ENGINE_IFB     ] = "ifb",
81 	[NVKM_ENGINE_ME      ] = "me",
82 	[NVKM_ENGINE_MPEG    ] = "mpeg",
83 	[NVKM_ENGINE_MSENC   ] = "msenc",
84 	[NVKM_ENGINE_MSPDEC  ] = "mspdec",
85 	[NVKM_ENGINE_MSPPP   ] = "msppp",
86 	[NVKM_ENGINE_MSVLD   ] = "msvld",
87 	[NVKM_ENGINE_NVENC0  ] = "nvenc0",
88 	[NVKM_ENGINE_NVENC1  ] = "nvenc1",
89 	[NVKM_ENGINE_NVENC2  ] = "nvenc2",
90 	[NVKM_ENGINE_NVDEC0  ] = "nvdec0",
91 	[NVKM_ENGINE_NVDEC1  ] = "nvdec1",
92 	[NVKM_ENGINE_NVDEC2  ] = "nvdec2",
93 	[NVKM_ENGINE_PM      ] = "pm",
94 	[NVKM_ENGINE_SEC     ] = "sec",
95 	[NVKM_ENGINE_SEC2    ] = "sec2",
96 	[NVKM_ENGINE_SW      ] = "sw",
97 	[NVKM_ENGINE_VIC     ] = "vic",
98 	[NVKM_ENGINE_VP      ] = "vp",
99 };
100 
101 void
nvkm_subdev_intr(struct nvkm_subdev * subdev)102 nvkm_subdev_intr(struct nvkm_subdev *subdev)
103 {
104 	if (subdev->func->intr)
105 		subdev->func->intr(subdev);
106 }
107 
108 int
nvkm_subdev_info(struct nvkm_subdev * subdev,u64 mthd,u64 * data)109 nvkm_subdev_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data)
110 {
111 	if (subdev->func->info)
112 		return subdev->func->info(subdev, mthd, data);
113 	return -ENOSYS;
114 }
115 
116 int
nvkm_subdev_fini(struct nvkm_subdev * subdev,bool suspend)117 nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
118 {
119 	struct nvkm_device *device = subdev->device;
120 	const char *action = suspend ? "suspend" : "fini";
121 	s64 time;
122 
123 	nvkm_trace(subdev, "%s running...\n", action);
124 	time = ktime_to_us(ktime_get());
125 
126 	if (subdev->func->fini) {
127 		int ret = subdev->func->fini(subdev, suspend);
128 		if (ret) {
129 			nvkm_error(subdev, "%s failed, %d\n", action, ret);
130 			if (suspend)
131 				return ret;
132 		}
133 	}
134 
135 	nvkm_mc_reset(device, subdev->index);
136 
137 	time = ktime_to_us(ktime_get()) - time;
138 	nvkm_trace(subdev, "%s completed in %"PRId64"us\n", action, time);
139 	return 0;
140 }
141 
142 int
nvkm_subdev_preinit(struct nvkm_subdev * subdev)143 nvkm_subdev_preinit(struct nvkm_subdev *subdev)
144 {
145 	s64 time;
146 
147 	nvkm_trace(subdev, "preinit running...\n");
148 	time = ktime_to_us(ktime_get());
149 
150 	if (subdev->func->preinit) {
151 		int ret = subdev->func->preinit(subdev);
152 		if (ret) {
153 			nvkm_error(subdev, "preinit failed, %d\n", ret);
154 			return ret;
155 		}
156 	}
157 
158 	time = ktime_to_us(ktime_get()) - time;
159 	nvkm_trace(subdev, "preinit completed in %"PRId64"us\n", time);
160 	return 0;
161 }
162 
163 int
nvkm_subdev_init(struct nvkm_subdev * subdev)164 nvkm_subdev_init(struct nvkm_subdev *subdev)
165 {
166 	s64 time;
167 	int ret;
168 
169 	nvkm_trace(subdev, "init running...\n");
170 	time = ktime_to_us(ktime_get());
171 
172 	if (subdev->func->oneinit && !subdev->oneinit) {
173 		s64 time;
174 		nvkm_trace(subdev, "one-time init running...\n");
175 		time = ktime_to_us(ktime_get());
176 		ret = subdev->func->oneinit(subdev);
177 		if (ret) {
178 			nvkm_error(subdev, "one-time init failed, %d\n", ret);
179 			return ret;
180 		}
181 
182 		subdev->oneinit = true;
183 		time = ktime_to_us(ktime_get()) - time;
184 		nvkm_trace(subdev, "one-time init completed in %"PRId64"us\n", time);
185 	}
186 
187 	if (subdev->func->init) {
188 		ret = subdev->func->init(subdev);
189 		if (ret) {
190 			nvkm_error(subdev, "init failed, %d\n", ret);
191 			return ret;
192 		}
193 	}
194 
195 	time = ktime_to_us(ktime_get()) - time;
196 	nvkm_trace(subdev, "init completed in %"PRId64"us\n", time);
197 	return 0;
198 }
199 
200 void
nvkm_subdev_del(struct nvkm_subdev ** psubdev)201 nvkm_subdev_del(struct nvkm_subdev **psubdev)
202 {
203 	struct nvkm_subdev *subdev = *psubdev;
204 	s64 time;
205 
206 	if (subdev && !WARN_ON(!subdev->func)) {
207 		nvkm_trace(subdev, "destroy running...\n");
208 		time = ktime_to_us(ktime_get());
209 		if (subdev->func->dtor)
210 			*psubdev = subdev->func->dtor(subdev);
211 		time = ktime_to_us(ktime_get()) - time;
212 		nvkm_trace(subdev, "destroy completed in %"PRId64"us\n", time);
213 		mutex_destroy(&subdev->mutex);
214 		kfree(*psubdev);
215 		*psubdev = NULL;
216 	}
217 }
218 
219 void
nvkm_subdev_ctor(const struct nvkm_subdev_func * func,struct nvkm_device * device,int index,struct nvkm_subdev * subdev)220 nvkm_subdev_ctor(const struct nvkm_subdev_func *func,
221 		 struct nvkm_device *device, int index,
222 		 struct nvkm_subdev *subdev)
223 {
224 	const char *name = nvkm_subdev_name[index];
225 	subdev->func = func;
226 	subdev->device = device;
227 	subdev->index = index;
228 
229 	__mutex_init(&subdev->mutex, name, &nvkm_subdev_lock_class[index]);
230 	subdev->debug = nvkm_dbgopt(device->dbgopt, name);
231 }
232