diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2013-02-13 00:29:11 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-11-08 00:40:05 -0500 |
commit | aa4d7a4d55ab375b2f1c894ba680186e4a7c6fd6 (patch) | |
tree | 4c88b0a8f6e8e5cd1256228f06331dd31495748b | |
parent | 2984506fb6172712f83e573319baf7dbd0eb9028 (diff) |
drm/nouveau/perfmon: initial infrastructure to expose performance counters
Internal use only at this point. Userspace later.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
22 files changed, 1616 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 3859958581c2..7805ebc7255a 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -246,6 +246,15 @@ nouveau-y += core/engine/mpeg/nv40.o | |||
246 | nouveau-y += core/engine/mpeg/nv44.o | 246 | nouveau-y += core/engine/mpeg/nv44.o |
247 | nouveau-y += core/engine/mpeg/nv50.o | 247 | nouveau-y += core/engine/mpeg/nv50.o |
248 | nouveau-y += core/engine/mpeg/nv84.o | 248 | nouveau-y += core/engine/mpeg/nv84.o |
249 | nouveau-y += core/engine/perfmon/base.o | ||
250 | nouveau-y += core/engine/perfmon/daemon.o | ||
251 | nouveau-y += core/engine/perfmon/nv40.o | ||
252 | nouveau-y += core/engine/perfmon/nv50.o | ||
253 | nouveau-y += core/engine/perfmon/nv84.o | ||
254 | nouveau-y += core/engine/perfmon/nva3.o | ||
255 | nouveau-y += core/engine/perfmon/nvc0.o | ||
256 | nouveau-y += core/engine/perfmon/nve0.o | ||
257 | nouveau-y += core/engine/perfmon/nvf0.o | ||
249 | nouveau-y += core/engine/ppp/nv98.o | 258 | nouveau-y += core/engine/ppp/nv98.o |
250 | nouveau-y += core/engine/ppp/nvc0.o | 259 | nouveau-y += core/engine/ppp/nvc0.o |
251 | nouveau-y += core/engine/software/nv04.o | 260 | nouveau-y += core/engine/software/nv04.o |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index 894985aa84f3..f775f43f3f77 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c | |||
@@ -77,6 +77,7 @@ static const u64 disable_map[] = { | |||
77 | [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE, | 77 | [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE, |
78 | [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE, | 78 | [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE, |
79 | [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE, | 79 | [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE, |
80 | [NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE, | ||
80 | [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO, | 81 | [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO, |
81 | [NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO, | 82 | [NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO, |
82 | [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH, | 83 | [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH, |
@@ -123,7 +124,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, | |||
123 | ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL, | 124 | ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL, |
124 | (1ULL << NVDEV_ENGINE_DMAOBJ) | | 125 | (1ULL << NVDEV_ENGINE_DMAOBJ) | |
125 | (1ULL << NVDEV_ENGINE_FIFO) | | 126 | (1ULL << NVDEV_ENGINE_FIFO) | |
126 | (1ULL << NVDEV_ENGINE_DISP), &devobj); | 127 | (1ULL << NVDEV_ENGINE_DISP) | |
128 | (1ULL << NVDEV_ENGINE_PERFMON), &devobj); | ||
127 | *pobject = nv_object(devobj); | 129 | *pobject = nv_object(devobj); |
128 | if (ret) | 130 | if (ret) |
129 | return ret; | 131 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index 7bcc4c9ce13f..97458cba2bef 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <engine/graph.h> | 43 | #include <engine/graph.h> |
44 | #include <engine/mpeg.h> | 44 | #include <engine/mpeg.h> |
45 | #include <engine/disp.h> | 45 | #include <engine/disp.h> |
46 | #include <engine/perfmon.h> | ||
46 | 47 | ||
47 | int | 48 | int |
48 | nv40_identify(struct nouveau_device *device) | 49 | nv40_identify(struct nouveau_device *device) |
@@ -68,6 +69,7 @@ nv40_identify(struct nouveau_device *device) | |||
68 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 69 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
69 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; | 70 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; |
70 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 71 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
72 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
71 | break; | 73 | break; |
72 | case 0x41: | 74 | case 0x41: |
73 | device->cname = "NV41"; | 75 | device->cname = "NV41"; |
@@ -89,6 +91,7 @@ nv40_identify(struct nouveau_device *device) | |||
89 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 91 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
90 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; | 92 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; |
91 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 93 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
94 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
92 | break; | 95 | break; |
93 | case 0x42: | 96 | case 0x42: |
94 | device->cname = "NV42"; | 97 | device->cname = "NV42"; |
@@ -110,6 +113,7 @@ nv40_identify(struct nouveau_device *device) | |||
110 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 113 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
111 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; | 114 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; |
112 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 115 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
116 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
113 | break; | 117 | break; |
114 | case 0x43: | 118 | case 0x43: |
115 | device->cname = "NV43"; | 119 | device->cname = "NV43"; |
@@ -131,6 +135,7 @@ nv40_identify(struct nouveau_device *device) | |||
131 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 135 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
132 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; | 136 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; |
133 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 137 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
138 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
134 | break; | 139 | break; |
135 | case 0x45: | 140 | case 0x45: |
136 | device->cname = "NV45"; | 141 | device->cname = "NV45"; |
@@ -152,6 +157,7 @@ nv40_identify(struct nouveau_device *device) | |||
152 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 157 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
153 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 158 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
154 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 159 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
160 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
155 | break; | 161 | break; |
156 | case 0x47: | 162 | case 0x47: |
157 | device->cname = "G70"; | 163 | device->cname = "G70"; |
@@ -173,6 +179,7 @@ nv40_identify(struct nouveau_device *device) | |||
173 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 179 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
174 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 180 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
175 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 181 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
182 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
176 | break; | 183 | break; |
177 | case 0x49: | 184 | case 0x49: |
178 | device->cname = "G71"; | 185 | device->cname = "G71"; |
@@ -194,6 +201,7 @@ nv40_identify(struct nouveau_device *device) | |||
194 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 201 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
195 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 202 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
196 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 203 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
204 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
197 | break; | 205 | break; |
198 | case 0x4b: | 206 | case 0x4b: |
199 | device->cname = "G73"; | 207 | device->cname = "G73"; |
@@ -215,6 +223,7 @@ nv40_identify(struct nouveau_device *device) | |||
215 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 223 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
216 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 224 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
217 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 225 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
226 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
218 | break; | 227 | break; |
219 | case 0x44: | 228 | case 0x44: |
220 | device->cname = "NV44"; | 229 | device->cname = "NV44"; |
@@ -236,6 +245,7 @@ nv40_identify(struct nouveau_device *device) | |||
236 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 245 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
237 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 246 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
238 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 247 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
248 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
239 | break; | 249 | break; |
240 | case 0x46: | 250 | case 0x46: |
241 | device->cname = "G72"; | 251 | device->cname = "G72"; |
@@ -257,6 +267,7 @@ nv40_identify(struct nouveau_device *device) | |||
257 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 267 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
258 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 268 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
259 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 269 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
270 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
260 | break; | 271 | break; |
261 | case 0x4a: | 272 | case 0x4a: |
262 | device->cname = "NV44A"; | 273 | device->cname = "NV44A"; |
@@ -278,6 +289,7 @@ nv40_identify(struct nouveau_device *device) | |||
278 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 289 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
279 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 290 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
280 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 291 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
292 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
281 | break; | 293 | break; |
282 | case 0x4c: | 294 | case 0x4c: |
283 | device->cname = "C61"; | 295 | device->cname = "C61"; |
@@ -299,6 +311,7 @@ nv40_identify(struct nouveau_device *device) | |||
299 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 311 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
300 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 312 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
301 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 313 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
314 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
302 | break; | 315 | break; |
303 | case 0x4e: | 316 | case 0x4e: |
304 | device->cname = "C51"; | 317 | device->cname = "C51"; |
@@ -320,6 +333,7 @@ nv40_identify(struct nouveau_device *device) | |||
320 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 333 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
321 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 334 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
322 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 335 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
336 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
323 | break; | 337 | break; |
324 | case 0x63: | 338 | case 0x63: |
325 | device->cname = "C73"; | 339 | device->cname = "C73"; |
@@ -341,6 +355,7 @@ nv40_identify(struct nouveau_device *device) | |||
341 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 355 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
342 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 356 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
343 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 357 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
358 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
344 | break; | 359 | break; |
345 | case 0x67: | 360 | case 0x67: |
346 | device->cname = "C67"; | 361 | device->cname = "C67"; |
@@ -362,6 +377,7 @@ nv40_identify(struct nouveau_device *device) | |||
362 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 377 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
363 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 378 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
364 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 379 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
380 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
365 | break; | 381 | break; |
366 | case 0x68: | 382 | case 0x68: |
367 | device->cname = "C68"; | 383 | device->cname = "C68"; |
@@ -383,6 +399,7 @@ nv40_identify(struct nouveau_device *device) | |||
383 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; | 399 | device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; |
384 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; | 400 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; |
385 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; | 401 | device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; |
402 | device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; | ||
386 | break; | 403 | break; |
387 | default: | 404 | default: |
388 | nv_fatal(device, "unknown Curie chipset\n"); | 405 | nv_fatal(device, "unknown Curie chipset\n"); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c index f44a2baecc79..671a6f4f4d94 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <engine/ppp.h> | 50 | #include <engine/ppp.h> |
51 | #include <engine/copy.h> | 51 | #include <engine/copy.h> |
52 | #include <engine/disp.h> | 52 | #include <engine/disp.h> |
53 | #include <engine/perfmon.h> | ||
53 | 54 | ||
54 | int | 55 | int |
55 | nv50_identify(struct nouveau_device *device) | 56 | nv50_identify(struct nouveau_device *device) |
@@ -77,6 +78,7 @@ nv50_identify(struct nouveau_device *device) | |||
77 | device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; | 78 | device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; |
78 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass; | 79 | device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass; |
79 | device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass; | 80 | device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass; |
81 | device->oclass[NVDEV_ENGINE_PERFMON] = nv50_perfmon_oclass; | ||
80 | break; | 82 | break; |
81 | case 0x84: | 83 | case 0x84: |
82 | device->cname = "G84"; | 84 | device->cname = "G84"; |
@@ -103,6 +105,7 @@ nv50_identify(struct nouveau_device *device) | |||
103 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; | 105 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; |
104 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; | 106 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; |
105 | device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; | 107 | device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; |
108 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
106 | break; | 109 | break; |
107 | case 0x86: | 110 | case 0x86: |
108 | device->cname = "G86"; | 111 | device->cname = "G86"; |
@@ -129,6 +132,7 @@ nv50_identify(struct nouveau_device *device) | |||
129 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; | 132 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; |
130 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; | 133 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; |
131 | device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; | 134 | device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; |
135 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
132 | break; | 136 | break; |
133 | case 0x92: | 137 | case 0x92: |
134 | device->cname = "G92"; | 138 | device->cname = "G92"; |
@@ -155,6 +159,7 @@ nv50_identify(struct nouveau_device *device) | |||
155 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; | 159 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; |
156 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; | 160 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; |
157 | device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; | 161 | device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; |
162 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
158 | break; | 163 | break; |
159 | case 0x94: | 164 | case 0x94: |
160 | device->cname = "G94"; | 165 | device->cname = "G94"; |
@@ -181,6 +186,7 @@ nv50_identify(struct nouveau_device *device) | |||
181 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; | 186 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; |
182 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; | 187 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; |
183 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; | 188 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; |
189 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
184 | break; | 190 | break; |
185 | case 0x96: | 191 | case 0x96: |
186 | device->cname = "G96"; | 192 | device->cname = "G96"; |
@@ -207,6 +213,7 @@ nv50_identify(struct nouveau_device *device) | |||
207 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; | 213 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; |
208 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; | 214 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; |
209 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; | 215 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; |
216 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
210 | break; | 217 | break; |
211 | case 0x98: | 218 | case 0x98: |
212 | device->cname = "G98"; | 219 | device->cname = "G98"; |
@@ -233,6 +240,7 @@ nv50_identify(struct nouveau_device *device) | |||
233 | device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; | 240 | device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; |
234 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 241 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
235 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; | 242 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; |
243 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
236 | break; | 244 | break; |
237 | case 0xa0: | 245 | case 0xa0: |
238 | device->cname = "G200"; | 246 | device->cname = "G200"; |
@@ -259,6 +267,7 @@ nv50_identify(struct nouveau_device *device) | |||
259 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; | 267 | device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; |
260 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; | 268 | device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; |
261 | device->oclass[NVDEV_ENGINE_DISP ] = &nva0_disp_oclass; | 269 | device->oclass[NVDEV_ENGINE_DISP ] = &nva0_disp_oclass; |
270 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
262 | break; | 271 | break; |
263 | case 0xaa: | 272 | case 0xaa: |
264 | device->cname = "MCP77/MCP78"; | 273 | device->cname = "MCP77/MCP78"; |
@@ -285,6 +294,7 @@ nv50_identify(struct nouveau_device *device) | |||
285 | device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; | 294 | device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; |
286 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 295 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
287 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; | 296 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; |
297 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
288 | break; | 298 | break; |
289 | case 0xac: | 299 | case 0xac: |
290 | device->cname = "MCP79/MCP7A"; | 300 | device->cname = "MCP79/MCP7A"; |
@@ -311,6 +321,7 @@ nv50_identify(struct nouveau_device *device) | |||
311 | device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; | 321 | device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; |
312 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 322 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
313 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; | 323 | device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; |
324 | device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; | ||
314 | break; | 325 | break; |
315 | case 0xa3: | 326 | case 0xa3: |
316 | device->cname = "GT215"; | 327 | device->cname = "GT215"; |
@@ -339,6 +350,7 @@ nv50_identify(struct nouveau_device *device) | |||
339 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 350 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
340 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; | 351 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; |
341 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 352 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
353 | device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; | ||
342 | break; | 354 | break; |
343 | case 0xa5: | 355 | case 0xa5: |
344 | device->cname = "GT216"; | 356 | device->cname = "GT216"; |
@@ -366,6 +378,7 @@ nv50_identify(struct nouveau_device *device) | |||
366 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 378 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
367 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; | 379 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; |
368 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 380 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
381 | device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; | ||
369 | break; | 382 | break; |
370 | case 0xa8: | 383 | case 0xa8: |
371 | device->cname = "GT218"; | 384 | device->cname = "GT218"; |
@@ -393,6 +406,7 @@ nv50_identify(struct nouveau_device *device) | |||
393 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 406 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
394 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; | 407 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; |
395 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 408 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
409 | device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; | ||
396 | break; | 410 | break; |
397 | case 0xaf: | 411 | case 0xaf: |
398 | device->cname = "MCP89"; | 412 | device->cname = "MCP89"; |
@@ -420,6 +434,7 @@ nv50_identify(struct nouveau_device *device) | |||
420 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; | 434 | device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; |
421 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; | 435 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; |
422 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 436 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
437 | device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; | ||
423 | break; | 438 | break; |
424 | default: | 439 | default: |
425 | nv_fatal(device, "unknown Tesla chipset\n"); | 440 | nv_fatal(device, "unknown Tesla chipset\n"); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 7db87cf231c7..94d5090d8eb9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <engine/ppp.h> | 50 | #include <engine/ppp.h> |
51 | #include <engine/copy.h> | 51 | #include <engine/copy.h> |
52 | #include <engine/disp.h> | 52 | #include <engine/disp.h> |
53 | #include <engine/perfmon.h> | ||
53 | 54 | ||
54 | int | 55 | int |
55 | nvc0_identify(struct nouveau_device *device) | 56 | nvc0_identify(struct nouveau_device *device) |
@@ -84,6 +85,7 @@ nvc0_identify(struct nouveau_device *device) | |||
84 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 85 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
85 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | 86 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; |
86 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 87 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
88 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
87 | break; | 89 | break; |
88 | case 0xc4: | 90 | case 0xc4: |
89 | device->cname = "GF104"; | 91 | device->cname = "GF104"; |
@@ -114,6 +116,7 @@ nvc0_identify(struct nouveau_device *device) | |||
114 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 116 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
115 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | 117 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; |
116 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 118 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
119 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
117 | break; | 120 | break; |
118 | case 0xc3: | 121 | case 0xc3: |
119 | device->cname = "GF106"; | 122 | device->cname = "GF106"; |
@@ -143,6 +146,7 @@ nvc0_identify(struct nouveau_device *device) | |||
143 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 146 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
144 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 147 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
145 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 148 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
149 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
146 | break; | 150 | break; |
147 | case 0xce: | 151 | case 0xce: |
148 | device->cname = "GF114"; | 152 | device->cname = "GF114"; |
@@ -173,6 +177,7 @@ nvc0_identify(struct nouveau_device *device) | |||
173 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 177 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
174 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | 178 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; |
175 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 179 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
180 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
176 | break; | 181 | break; |
177 | case 0xcf: | 182 | case 0xcf: |
178 | device->cname = "GF116"; | 183 | device->cname = "GF116"; |
@@ -203,6 +208,7 @@ nvc0_identify(struct nouveau_device *device) | |||
203 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 208 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
204 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | 209 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; |
205 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 210 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
211 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
206 | break; | 212 | break; |
207 | case 0xc1: | 213 | case 0xc1: |
208 | device->cname = "GF108"; | 214 | device->cname = "GF108"; |
@@ -232,6 +238,7 @@ nvc0_identify(struct nouveau_device *device) | |||
232 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 238 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
233 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 239 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
234 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 240 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
241 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
235 | break; | 242 | break; |
236 | case 0xc8: | 243 | case 0xc8: |
237 | device->cname = "GF110"; | 244 | device->cname = "GF110"; |
@@ -262,6 +269,7 @@ nvc0_identify(struct nouveau_device *device) | |||
262 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 269 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
263 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | 270 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; |
264 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 271 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
272 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
265 | break; | 273 | break; |
266 | case 0xd9: | 274 | case 0xd9: |
267 | device->cname = "GF119"; | 275 | device->cname = "GF119"; |
@@ -291,6 +299,7 @@ nvc0_identify(struct nouveau_device *device) | |||
291 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 299 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
292 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 300 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
293 | device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; | 301 | device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; |
302 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
294 | break; | 303 | break; |
295 | case 0xd7: | 304 | case 0xd7: |
296 | device->cname = "GF117"; | 305 | device->cname = "GF117"; |
@@ -319,6 +328,7 @@ nvc0_identify(struct nouveau_device *device) | |||
319 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 328 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
320 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 329 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
321 | device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; | 330 | device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; |
331 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; | ||
322 | break; | 332 | break; |
323 | default: | 333 | default: |
324 | nv_fatal(device, "unknown Fermi chipset\n"); | 334 | nv_fatal(device, "unknown Fermi chipset\n"); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 90b095c0875f..f3a7c1b3ea7c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <engine/bsp.h> | 50 | #include <engine/bsp.h> |
51 | #include <engine/vp.h> | 51 | #include <engine/vp.h> |
52 | #include <engine/ppp.h> | 52 | #include <engine/ppp.h> |
53 | #include <engine/perfmon.h> | ||
53 | 54 | ||
54 | int | 55 | int |
55 | nve0_identify(struct nouveau_device *device) | 56 | nve0_identify(struct nouveau_device *device) |
@@ -85,6 +86,7 @@ nve0_identify(struct nouveau_device *device) | |||
85 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | 86 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; |
86 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | 87 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; |
87 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 88 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
89 | device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; | ||
88 | break; | 90 | break; |
89 | case 0xe7: | 91 | case 0xe7: |
90 | device->cname = "GK107"; | 92 | device->cname = "GK107"; |
@@ -116,6 +118,7 @@ nve0_identify(struct nouveau_device *device) | |||
116 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | 118 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; |
117 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | 119 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; |
118 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 120 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
121 | device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; | ||
119 | break; | 122 | break; |
120 | case 0xe6: | 123 | case 0xe6: |
121 | device->cname = "GK106"; | 124 | device->cname = "GK106"; |
@@ -147,6 +150,7 @@ nve0_identify(struct nouveau_device *device) | |||
147 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | 150 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; |
148 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | 151 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; |
149 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 152 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
153 | device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; | ||
150 | break; | 154 | break; |
151 | case 0xf0: | 155 | case 0xf0: |
152 | device->cname = "GK110"; | 156 | device->cname = "GK110"; |
@@ -180,6 +184,7 @@ nve0_identify(struct nouveau_device *device) | |||
180 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | 184 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; |
181 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 185 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
182 | #endif | 186 | #endif |
187 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; | ||
183 | break; | 188 | break; |
184 | case 0x108: | 189 | case 0x108: |
185 | device->cname = "GK208"; | 190 | device->cname = "GK208"; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 3f4f35cc3848..434bb4b0fa2e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c | |||
@@ -1138,7 +1138,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
1138 | if (ret) | 1138 | if (ret) |
1139 | return ret; | 1139 | return ret; |
1140 | 1140 | ||
1141 | nv_subdev(priv)->unit = 0x18001000; | 1141 | nv_subdev(priv)->unit = 0x08001000; |
1142 | nv_subdev(priv)->intr = nvc0_graph_intr; | 1142 | nv_subdev(priv)->intr = nvc0_graph_intr; |
1143 | 1143 | ||
1144 | priv->base.units = nvc0_graph_units; | 1144 | priv->base.units = nvc0_graph_units; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c new file mode 100644 index 000000000000..e9c5e51943ef --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c | |||
@@ -0,0 +1,449 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include <core/option.h> | ||
26 | #include <core/class.h> | ||
27 | |||
28 | #include <subdev/clock.h> | ||
29 | |||
30 | #include "priv.h" | ||
31 | |||
32 | #define QUAD_MASK 0x0f | ||
33 | #define QUAD_FREE 0x01 | ||
34 | |||
35 | static struct nouveau_perfsig * | ||
36 | nouveau_perfsig_find_(struct nouveau_perfdom *dom, const char *name, u32 size) | ||
37 | { | ||
38 | char path[64]; | ||
39 | int i; | ||
40 | |||
41 | if (name[0] != '/') { | ||
42 | for (i = 0; i < dom->signal_nr; i++) { | ||
43 | if ( dom->signal[i].name && | ||
44 | !strncmp(name, dom->signal[i].name, size)) | ||
45 | return &dom->signal[i]; | ||
46 | } | ||
47 | } else { | ||
48 | for (i = 0; i < dom->signal_nr; i++) { | ||
49 | snprintf(path, sizeof(path), "/%s/%02x", dom->name, i); | ||
50 | if (!strncmp(name, path, size)) | ||
51 | return &dom->signal[i]; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | return NULL; | ||
56 | } | ||
57 | |||
58 | struct nouveau_perfsig * | ||
59 | nouveau_perfsig_find(struct nouveau_perfmon *ppm, const char *name, u32 size, | ||
60 | struct nouveau_perfdom **pdom) | ||
61 | { | ||
62 | struct nouveau_perfdom *dom = *pdom; | ||
63 | struct nouveau_perfsig *sig; | ||
64 | |||
65 | if (dom == NULL) { | ||
66 | list_for_each_entry(dom, &ppm->domains, head) { | ||
67 | sig = nouveau_perfsig_find_(dom, name, size); | ||
68 | if (sig) { | ||
69 | *pdom = dom; | ||
70 | return sig; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | return NULL; | ||
75 | } | ||
76 | |||
77 | return nouveau_perfsig_find_(dom, name, size); | ||
78 | } | ||
79 | |||
80 | struct nouveau_perfctr * | ||
81 | nouveau_perfsig_wrap(struct nouveau_perfmon *ppm, const char *name, | ||
82 | struct nouveau_perfdom **pdom) | ||
83 | { | ||
84 | struct nouveau_perfsig *sig; | ||
85 | struct nouveau_perfctr *ctr; | ||
86 | |||
87 | sig = nouveau_perfsig_find(ppm, name, strlen(name), pdom); | ||
88 | if (!sig) | ||
89 | return NULL; | ||
90 | |||
91 | ctr = kzalloc(sizeof(*ctr), GFP_KERNEL); | ||
92 | if (ctr) { | ||
93 | ctr->signal[0] = sig; | ||
94 | ctr->logic_op = 0xaaaa; | ||
95 | } | ||
96 | |||
97 | return ctr; | ||
98 | } | ||
99 | |||
100 | /******************************************************************************* | ||
101 | * Perfmon object classes | ||
102 | ******************************************************************************/ | ||
103 | static int | ||
104 | nouveau_perfctr_query(struct nouveau_object *object, u32 mthd, | ||
105 | void *data, u32 size) | ||
106 | { | ||
107 | struct nouveau_device *device = nv_device(object); | ||
108 | struct nouveau_perfmon *ppm = (void *)object->engine; | ||
109 | struct nouveau_perfdom *dom = NULL, *chk; | ||
110 | struct nv_perfctr_query *args = data; | ||
111 | const bool all = nouveau_boolopt(device->cfgopt, "NvPmShowAll", false); | ||
112 | const bool raw = nouveau_boolopt(device->cfgopt, "NvPmUnnamed", all); | ||
113 | const char *name; | ||
114 | int tmp = 0, di, si; | ||
115 | char path[64]; | ||
116 | |||
117 | if (size < sizeof(*args)) | ||
118 | return -EINVAL; | ||
119 | |||
120 | di = (args->iter & 0xff000000) >> 24; | ||
121 | si = (args->iter & 0x00ffffff) - 1; | ||
122 | |||
123 | list_for_each_entry(chk, &ppm->domains, head) { | ||
124 | if (tmp++ == di) { | ||
125 | dom = chk; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | if (dom == NULL || si >= (int)dom->signal_nr) | ||
131 | return -EINVAL; | ||
132 | |||
133 | if (si >= 0) { | ||
134 | if (raw || !(name = dom->signal[si].name)) { | ||
135 | snprintf(path, sizeof(path), "/%s/%02x", dom->name, si); | ||
136 | name = path; | ||
137 | } | ||
138 | |||
139 | if (args->name) | ||
140 | strncpy(args->name, name, args->size); | ||
141 | args->size = strlen(name) + 1; | ||
142 | } | ||
143 | |||
144 | do { | ||
145 | while (++si < dom->signal_nr) { | ||
146 | if (all || dom->signal[si].name) { | ||
147 | args->iter = (di << 24) | ++si; | ||
148 | return 0; | ||
149 | } | ||
150 | } | ||
151 | si = -1; | ||
152 | di = di + 1; | ||
153 | dom = list_entry(dom->head.next, typeof(*dom), head); | ||
154 | } while (&dom->head != &ppm->domains); | ||
155 | |||
156 | args->iter = 0xffffffff; | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int | ||
161 | nouveau_perfctr_sample(struct nouveau_object *object, u32 mthd, | ||
162 | void *data, u32 size) | ||
163 | { | ||
164 | struct nouveau_perfmon *ppm = (void *)object->engine; | ||
165 | struct nouveau_perfctr *ctr, *tmp; | ||
166 | struct nouveau_perfdom *dom; | ||
167 | struct nv_perfctr_sample *args = data; | ||
168 | |||
169 | if (size < sizeof(*args)) | ||
170 | return -EINVAL; | ||
171 | ppm->sequence++; | ||
172 | |||
173 | list_for_each_entry(dom, &ppm->domains, head) { | ||
174 | /* sample previous batch of counters */ | ||
175 | if (dom->quad != QUAD_MASK) { | ||
176 | dom->func->next(ppm, dom); | ||
177 | tmp = NULL; | ||
178 | while (!list_empty(&dom->list)) { | ||
179 | ctr = list_first_entry(&dom->list, | ||
180 | typeof(*ctr), head); | ||
181 | if (ctr->slot < 0) break; | ||
182 | if ( tmp && tmp == ctr) break; | ||
183 | if (!tmp) tmp = ctr; | ||
184 | dom->func->read(ppm, dom, ctr); | ||
185 | ctr->slot = -1; | ||
186 | list_move_tail(&ctr->head, &dom->list); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | dom->quad = QUAD_MASK; | ||
191 | |||
192 | /* setup next batch of counters for sampling */ | ||
193 | list_for_each_entry(ctr, &dom->list, head) { | ||
194 | ctr->slot = ffs(dom->quad) - 1; | ||
195 | if (ctr->slot < 0) | ||
196 | break; | ||
197 | dom->quad &= ~(QUAD_FREE << ctr->slot); | ||
198 | dom->func->init(ppm, dom, ctr); | ||
199 | } | ||
200 | |||
201 | if (dom->quad != QUAD_MASK) | ||
202 | dom->func->next(ppm, dom); | ||
203 | } | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int | ||
209 | nouveau_perfctr_read(struct nouveau_object *object, u32 mthd, | ||
210 | void *data, u32 size) | ||
211 | { | ||
212 | struct nouveau_perfctr *ctr = (void *)object; | ||
213 | struct nv_perfctr_read *args = data; | ||
214 | |||
215 | if (size < sizeof(*args)) | ||
216 | return -EINVAL; | ||
217 | if (!ctr->clk) | ||
218 | return -EAGAIN; | ||
219 | |||
220 | args->clk = ctr->clk; | ||
221 | args->ctr = ctr->ctr; | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static void | ||
226 | nouveau_perfctr_dtor(struct nouveau_object *object) | ||
227 | { | ||
228 | struct nouveau_perfctr *ctr = (void *)object; | ||
229 | if (ctr->head.next) | ||
230 | list_del(&ctr->head); | ||
231 | nouveau_object_destroy(&ctr->base); | ||
232 | } | ||
233 | |||
234 | static int | ||
235 | nouveau_perfctr_ctor(struct nouveau_object *parent, | ||
236 | struct nouveau_object *engine, | ||
237 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
238 | struct nouveau_object **pobject) | ||
239 | { | ||
240 | struct nouveau_perfmon *ppm = (void *)engine; | ||
241 | struct nouveau_perfdom *dom = NULL; | ||
242 | struct nouveau_perfsig *sig[4] = {}; | ||
243 | struct nouveau_perfctr *ctr; | ||
244 | struct nv_perfctr_class *args = data; | ||
245 | int ret, i; | ||
246 | |||
247 | if (size < sizeof(*args)) | ||
248 | return -EINVAL; | ||
249 | |||
250 | for (i = 0; i < ARRAY_SIZE(args->signal) && args->signal[i].name; i++) { | ||
251 | sig[i] = nouveau_perfsig_find(ppm, args->signal[i].name, | ||
252 | args->signal[i].size, &dom); | ||
253 | if (!sig[i]) | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | |||
257 | ret = nouveau_object_create(parent, engine, oclass, 0, &ctr); | ||
258 | *pobject = nv_object(ctr); | ||
259 | if (ret) | ||
260 | return ret; | ||
261 | |||
262 | ctr->slot = -1; | ||
263 | ctr->logic_op = args->logic_op; | ||
264 | ctr->signal[0] = sig[0]; | ||
265 | ctr->signal[1] = sig[1]; | ||
266 | ctr->signal[2] = sig[2]; | ||
267 | ctr->signal[3] = sig[3]; | ||
268 | if (dom) | ||
269 | list_add_tail(&ctr->head, &dom->list); | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static struct nouveau_ofuncs | ||
274 | nouveau_perfctr_ofuncs = { | ||
275 | .ctor = nouveau_perfctr_ctor, | ||
276 | .dtor = nouveau_perfctr_dtor, | ||
277 | .init = nouveau_object_init, | ||
278 | .fini = nouveau_object_fini, | ||
279 | }; | ||
280 | |||
281 | static struct nouveau_omthds | ||
282 | nouveau_perfctr_omthds[] = { | ||
283 | { NV_PERFCTR_QUERY, NV_PERFCTR_QUERY, nouveau_perfctr_query }, | ||
284 | { NV_PERFCTR_SAMPLE, NV_PERFCTR_SAMPLE, nouveau_perfctr_sample }, | ||
285 | { NV_PERFCTR_READ, NV_PERFCTR_READ, nouveau_perfctr_read }, | ||
286 | {} | ||
287 | }; | ||
288 | |||
289 | struct nouveau_oclass | ||
290 | nouveau_perfmon_sclass[] = { | ||
291 | { .handle = NV_PERFCTR_CLASS, | ||
292 | .ofuncs = &nouveau_perfctr_ofuncs, | ||
293 | .omthds = nouveau_perfctr_omthds, | ||
294 | }, | ||
295 | {}, | ||
296 | }; | ||
297 | |||
298 | /******************************************************************************* | ||
299 | * PPM context | ||
300 | ******************************************************************************/ | ||
301 | static void | ||
302 | nouveau_perfctx_dtor(struct nouveau_object *object) | ||
303 | { | ||
304 | struct nouveau_perfmon *ppm = (void *)object->engine; | ||
305 | mutex_lock(&nv_subdev(ppm)->mutex); | ||
306 | ppm->context = NULL; | ||
307 | mutex_unlock(&nv_subdev(ppm)->mutex); | ||
308 | } | ||
309 | |||
310 | static int | ||
311 | nouveau_perfctx_ctor(struct nouveau_object *parent, | ||
312 | struct nouveau_object *engine, | ||
313 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
314 | struct nouveau_object **pobject) | ||
315 | { | ||
316 | struct nouveau_perfmon *ppm = (void *)engine; | ||
317 | struct nouveau_perfctx *ctx; | ||
318 | int ret; | ||
319 | |||
320 | ret = nouveau_engctx_create(parent, engine, oclass, NULL, | ||
321 | 0, 0, 0, &ctx); | ||
322 | *pobject = nv_object(ctx); | ||
323 | if (ret) | ||
324 | return ret; | ||
325 | |||
326 | mutex_lock(&nv_subdev(ppm)->mutex); | ||
327 | if (ppm->context == NULL) | ||
328 | ppm->context = ctx; | ||
329 | mutex_unlock(&nv_subdev(ppm)->mutex); | ||
330 | |||
331 | if (ctx != ppm->context) | ||
332 | return -EBUSY; | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | struct nouveau_oclass | ||
338 | nouveau_perfmon_cclass = { | ||
339 | .handle = NV_ENGCTX(PERFMON, 0x00), | ||
340 | .ofuncs = &(struct nouveau_ofuncs) { | ||
341 | .ctor = nouveau_perfctx_ctor, | ||
342 | .dtor = nouveau_perfctx_dtor, | ||
343 | .init = _nouveau_engctx_init, | ||
344 | .fini = _nouveau_engctx_fini, | ||
345 | }, | ||
346 | }; | ||
347 | |||
348 | /******************************************************************************* | ||
349 | * PPM engine/subdev functions | ||
350 | ******************************************************************************/ | ||
351 | int | ||
352 | nouveau_perfdom_new(struct nouveau_perfmon *ppm, const char *name, u32 mask, | ||
353 | u32 base, u32 size_unit, u32 size_domain, | ||
354 | const struct nouveau_specdom *spec) | ||
355 | { | ||
356 | const struct nouveau_specdom *sdom; | ||
357 | const struct nouveau_specsig *ssig; | ||
358 | struct nouveau_perfdom *dom; | ||
359 | int i; | ||
360 | |||
361 | for (i = 0; i == 0 || mask; i++) { | ||
362 | u32 addr = base + (i * size_unit); | ||
363 | if (i && !(mask & (1 << i))) | ||
364 | continue; | ||
365 | |||
366 | sdom = spec; | ||
367 | while (sdom->signal_nr) { | ||
368 | dom = kzalloc(sizeof(*dom) + sdom->signal_nr * | ||
369 | sizeof(*dom->signal), GFP_KERNEL); | ||
370 | if (!dom) | ||
371 | return -ENOMEM; | ||
372 | |||
373 | if (mask) { | ||
374 | snprintf(dom->name, sizeof(dom->name), | ||
375 | "%s/%02x/%02x", name, i, | ||
376 | (int)(sdom - spec)); | ||
377 | } else { | ||
378 | snprintf(dom->name, sizeof(dom->name), | ||
379 | "%s/%02x", name, (int)(sdom - spec)); | ||
380 | } | ||
381 | |||
382 | list_add_tail(&dom->head, &ppm->domains); | ||
383 | INIT_LIST_HEAD(&dom->list); | ||
384 | dom->func = sdom->func; | ||
385 | dom->addr = addr; | ||
386 | dom->quad = QUAD_MASK; | ||
387 | dom->signal_nr = sdom->signal_nr; | ||
388 | |||
389 | ssig = (sdom++)->signal; | ||
390 | while (ssig->name) { | ||
391 | dom->signal[ssig->signal].name = ssig->name; | ||
392 | ssig++; | ||
393 | } | ||
394 | |||
395 | addr += size_domain; | ||
396 | } | ||
397 | |||
398 | mask &= ~(1 << i); | ||
399 | } | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | int | ||
405 | _nouveau_perfmon_fini(struct nouveau_object *object, bool suspend) | ||
406 | { | ||
407 | struct nouveau_perfmon *ppm = (void *)object; | ||
408 | return nouveau_engine_fini(&ppm->base, suspend); | ||
409 | } | ||
410 | |||
411 | int | ||
412 | _nouveau_perfmon_init(struct nouveau_object *object) | ||
413 | { | ||
414 | struct nouveau_perfmon *ppm = (void *)object; | ||
415 | return nouveau_engine_init(&ppm->base); | ||
416 | } | ||
417 | |||
418 | void | ||
419 | _nouveau_perfmon_dtor(struct nouveau_object *object) | ||
420 | { | ||
421 | struct nouveau_perfmon *ppm = (void *)object; | ||
422 | struct nouveau_perfdom *dom, *tmp; | ||
423 | |||
424 | list_for_each_entry_safe(dom, tmp, &ppm->domains, head) { | ||
425 | list_del(&dom->head); | ||
426 | kfree(dom); | ||
427 | } | ||
428 | |||
429 | nouveau_engine_destroy(&ppm->base); | ||
430 | } | ||
431 | |||
432 | int | ||
433 | nouveau_perfmon_create_(struct nouveau_object *parent, | ||
434 | struct nouveau_object *engine, | ||
435 | struct nouveau_oclass *oclass, | ||
436 | int length, void **pobject) | ||
437 | { | ||
438 | struct nouveau_perfmon *ppm; | ||
439 | int ret; | ||
440 | |||
441 | ret = nouveau_engine_create_(parent, engine, oclass, true, "PPM", | ||
442 | "perfmon", length, pobject); | ||
443 | ppm = *pobject; | ||
444 | if (ret) | ||
445 | return ret; | ||
446 | |||
447 | INIT_LIST_HEAD(&ppm->domains); | ||
448 | return 0; | ||
449 | } | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c new file mode 100644 index 000000000000..50696cc7b7d7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "priv.h" | ||
26 | |||
27 | static void | ||
28 | pwr_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, | ||
29 | struct nouveau_perfctr *ctr) | ||
30 | { | ||
31 | u32 mask = 0x00000000; | ||
32 | u32 ctrl = 0x00000001; | ||
33 | int i; | ||
34 | |||
35 | for (i = 0; i < ARRAY_SIZE(ctr->signal) && ctr->signal[i]; i++) | ||
36 | mask |= 1 << (ctr->signal[i] - dom->signal); | ||
37 | |||
38 | nv_wr32(ppm, 0x10a504 + (ctr->slot * 0x10), mask); | ||
39 | nv_wr32(ppm, 0x10a50c + (ctr->slot * 0x10), ctrl); | ||
40 | nv_wr32(ppm, 0x10a50c + (ppm->last * 0x10), 0x00000003); | ||
41 | } | ||
42 | |||
43 | static void | ||
44 | pwr_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, | ||
45 | struct nouveau_perfctr *ctr) | ||
46 | { | ||
47 | ctr->ctr = ppm->pwr[ctr->slot]; | ||
48 | ctr->clk = ppm->pwr[ppm->last]; | ||
49 | } | ||
50 | |||
51 | static void | ||
52 | pwr_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom) | ||
53 | { | ||
54 | int i; | ||
55 | |||
56 | for (i = 0; i <= ppm->last; i++) { | ||
57 | ppm->pwr[i] = nv_rd32(ppm, 0x10a508 + (i * 0x10)); | ||
58 | nv_wr32(ppm, 0x10a508 + (i * 0x10), 0x80000000); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | static const struct nouveau_funcdom | ||
63 | pwr_perfctr_func = { | ||
64 | .init = pwr_perfctr_init, | ||
65 | .read = pwr_perfctr_read, | ||
66 | .next = pwr_perfctr_next, | ||
67 | }; | ||
68 | |||
69 | const struct nouveau_specdom | ||
70 | nva3_perfmon_pwr[] = { | ||
71 | { 0x20, (const struct nouveau_specsig[]) { | ||
72 | { 0x00, "pwr_gr_idle" }, | ||
73 | { 0x04, "pwr_bsp_idle" }, | ||
74 | { 0x05, "pwr_vp_idle" }, | ||
75 | { 0x06, "pwr_ppp_idle" }, | ||
76 | { 0x13, "pwr_ce0_idle" }, | ||
77 | {} | ||
78 | }, &pwr_perfctr_func }, | ||
79 | {} | ||
80 | }; | ||
81 | |||
82 | const struct nouveau_specdom | ||
83 | nvc0_perfmon_pwr[] = { | ||
84 | { 0x20, (const struct nouveau_specsig[]) { | ||
85 | { 0x00, "pwr_gr_idle" }, | ||
86 | { 0x04, "pwr_bsp_idle" }, | ||
87 | { 0x05, "pwr_vp_idle" }, | ||
88 | { 0x06, "pwr_ppp_idle" }, | ||
89 | { 0x13, "pwr_ce0_idle" }, | ||
90 | { 0x14, "pwr_ce1_idle" }, | ||
91 | {} | ||
92 | }, &pwr_perfctr_func }, | ||
93 | {} | ||
94 | }; | ||
95 | |||
96 | const struct nouveau_specdom | ||
97 | nve0_perfmon_pwr[] = { | ||
98 | { 0x20, (const struct nouveau_specsig[]) { | ||
99 | { 0x00, "pwr_gr_idle" }, | ||
100 | { 0x04, "pwr_bsp_idle" }, | ||
101 | { 0x05, "pwr_vp_idle" }, | ||
102 | { 0x06, "pwr_ppp_idle" }, | ||
103 | { 0x13, "pwr_ce0_idle" }, | ||
104 | { 0x14, "pwr_ce1_idle" }, | ||
105 | { 0x15, "pwr_ce2_idle" }, | ||
106 | {} | ||
107 | }, &pwr_perfctr_func }, | ||
108 | {} | ||
109 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c new file mode 100644 index 000000000000..b2a10785adb1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nv40.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static void | ||
40 | nv40_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, | ||
41 | struct nouveau_perfctr *ctr) | ||
42 | { | ||
43 | struct nv40_perfmon_priv *priv = (void *)ppm; | ||
44 | struct nv40_perfmon_cntr *cntr = (void *)ctr; | ||
45 | u32 log = ctr->logic_op; | ||
46 | u32 src = 0x00000000; | ||
47 | int i; | ||
48 | |||
49 | for (i = 0; i < 4 && ctr->signal[i]; i++) | ||
50 | src |= (ctr->signal[i] - dom->signal) << (i * 8); | ||
51 | |||
52 | nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001); | ||
53 | nv_wr32(priv, 0x00a400 + dom->addr + (cntr->base.slot * 0x40), src); | ||
54 | nv_wr32(priv, 0x00a420 + dom->addr + (cntr->base.slot * 0x40), log); | ||
55 | } | ||
56 | |||
57 | static void | ||
58 | nv40_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, | ||
59 | struct nouveau_perfctr *ctr) | ||
60 | { | ||
61 | struct nv40_perfmon_priv *priv = (void *)ppm; | ||
62 | struct nv40_perfmon_cntr *cntr = (void *)ctr; | ||
63 | |||
64 | switch (cntr->base.slot) { | ||
65 | case 0: cntr->base.ctr = nv_rd32(priv, 0x00a700 + dom->addr); break; | ||
66 | case 1: cntr->base.ctr = nv_rd32(priv, 0x00a6c0 + dom->addr); break; | ||
67 | case 2: cntr->base.ctr = nv_rd32(priv, 0x00a680 + dom->addr); break; | ||
68 | case 3: cntr->base.ctr = nv_rd32(priv, 0x00a740 + dom->addr); break; | ||
69 | } | ||
70 | cntr->base.clk = nv_rd32(priv, 0x00a600 + dom->addr); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | nv40_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom) | ||
75 | { | ||
76 | struct nv40_perfmon_priv *priv = (void *)ppm; | ||
77 | if (priv->sequence != ppm->sequence) { | ||
78 | nv_wr32(priv, 0x400084, 0x00000020); | ||
79 | priv->sequence = ppm->sequence; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | const struct nouveau_funcdom | ||
84 | nv40_perfctr_func = { | ||
85 | .init = nv40_perfctr_init, | ||
86 | .read = nv40_perfctr_read, | ||
87 | .next = nv40_perfctr_next, | ||
88 | }; | ||
89 | |||
90 | static const struct nouveau_specdom | ||
91 | nv40_perfmon[] = { | ||
92 | { 0x20, (const struct nouveau_specsig[]) { | ||
93 | {} | ||
94 | }, &nv40_perfctr_func }, | ||
95 | { 0x20, (const struct nouveau_specsig[]) { | ||
96 | {} | ||
97 | }, &nv40_perfctr_func }, | ||
98 | { 0x20, (const struct nouveau_specsig[]) { | ||
99 | {} | ||
100 | }, &nv40_perfctr_func }, | ||
101 | { 0x20, (const struct nouveau_specsig[]) { | ||
102 | {} | ||
103 | }, &nv40_perfctr_func }, | ||
104 | { 0x20, (const struct nouveau_specsig[]) { | ||
105 | {} | ||
106 | }, &nv40_perfctr_func }, | ||
107 | {} | ||
108 | }; | ||
109 | |||
110 | int | ||
111 | nv40_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
112 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
113 | struct nouveau_object **pobject) | ||
114 | { | ||
115 | struct nv40_perfmon_oclass *mclass = (void *)oclass; | ||
116 | struct nv40_perfmon_priv *priv; | ||
117 | int ret; | ||
118 | |||
119 | ret = nouveau_perfmon_create(parent, engine, oclass, &priv); | ||
120 | *pobject = nv_object(priv); | ||
121 | if (ret) | ||
122 | return ret; | ||
123 | |||
124 | ret = nouveau_perfdom_new(&priv->base, "pm", 0, 0, 0, 4, mclass->doms); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | |||
128 | nv_engine(priv)->cclass = &nouveau_perfmon_cclass; | ||
129 | nv_engine(priv)->sclass = nouveau_perfmon_sclass; | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | struct nouveau_oclass * | ||
134 | nv40_perfmon_oclass = &(struct nv40_perfmon_oclass) { | ||
135 | .base.handle = NV_ENGINE(PERFMON, 0x40), | ||
136 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
137 | .ctor = nv40_perfmon_ctor, | ||
138 | .dtor = _nouveau_perfmon_dtor, | ||
139 | .init = _nouveau_perfmon_init, | ||
140 | .fini = _nouveau_perfmon_fini, | ||
141 | }, | ||
142 | .doms = nv40_perfmon, | ||
143 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h new file mode 100644 index 000000000000..1b5792d1df14 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h | |||
@@ -0,0 +1,26 @@ | |||
1 | #ifndef __NVKM_PM_NV40_H__ | ||
2 | #define __NVKM_PM_NV40_H__ | ||
3 | |||
4 | #include "priv.h" | ||
5 | |||
6 | struct nv40_perfmon_oclass { | ||
7 | struct nouveau_oclass base; | ||
8 | const struct nouveau_specdom *doms; | ||
9 | }; | ||
10 | |||
11 | struct nv40_perfmon_priv { | ||
12 | struct nouveau_perfmon base; | ||
13 | u32 sequence; | ||
14 | }; | ||
15 | |||
16 | int nv40_perfmon_ctor(struct nouveau_object *, struct nouveau_object *, | ||
17 | struct nouveau_oclass *, void *data, u32 size, | ||
18 | struct nouveau_object **pobject); | ||
19 | |||
20 | struct nv40_perfmon_cntr { | ||
21 | struct nouveau_perfctr base; | ||
22 | }; | ||
23 | |||
24 | extern const struct nouveau_funcdom nv40_perfctr_func; | ||
25 | |||
26 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c new file mode 100644 index 000000000000..94217691fe67 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c | |||
@@ -0,0 +1,70 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nv40.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static const struct nouveau_specdom | ||
40 | nv50_perfmon[] = { | ||
41 | { 0x040, (const struct nouveau_specsig[]) { | ||
42 | {} | ||
43 | }, &nv40_perfctr_func }, | ||
44 | { 0x100, (const struct nouveau_specsig[]) { | ||
45 | { 0xc8, "gr_idle" }, | ||
46 | {} | ||
47 | }, &nv40_perfctr_func }, | ||
48 | { 0x100, (const struct nouveau_specsig[]) { | ||
49 | {} | ||
50 | }, &nv40_perfctr_func }, | ||
51 | { 0x020, (const struct nouveau_specsig[]) { | ||
52 | {} | ||
53 | }, &nv40_perfctr_func }, | ||
54 | { 0x040, (const struct nouveau_specsig[]) { | ||
55 | {} | ||
56 | }, &nv40_perfctr_func }, | ||
57 | {} | ||
58 | }; | ||
59 | |||
60 | struct nouveau_oclass * | ||
61 | nv50_perfmon_oclass = &(struct nv40_perfmon_oclass) { | ||
62 | .base.handle = NV_ENGINE(PERFMON, 0x50), | ||
63 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
64 | .ctor = nv40_perfmon_ctor, | ||
65 | .dtor = _nouveau_perfmon_dtor, | ||
66 | .init = _nouveau_perfmon_init, | ||
67 | .fini = _nouveau_perfmon_fini, | ||
68 | }, | ||
69 | .doms = nv50_perfmon, | ||
70 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c new file mode 100644 index 000000000000..9232c7fc6253 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nv40.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static const struct nouveau_specdom | ||
40 | nv84_perfmon[] = { | ||
41 | { 0x20, (const struct nouveau_specsig[]) { | ||
42 | {} | ||
43 | }, &nv40_perfctr_func }, | ||
44 | { 0x20, (const struct nouveau_specsig[]) { | ||
45 | {} | ||
46 | }, &nv40_perfctr_func }, | ||
47 | { 0x20, (const struct nouveau_specsig[]) { | ||
48 | {} | ||
49 | }, &nv40_perfctr_func }, | ||
50 | { 0x20, (const struct nouveau_specsig[]) { | ||
51 | {} | ||
52 | }, &nv40_perfctr_func }, | ||
53 | { 0x20, (const struct nouveau_specsig[]) { | ||
54 | {} | ||
55 | }, &nv40_perfctr_func }, | ||
56 | { 0x20, (const struct nouveau_specsig[]) { | ||
57 | {} | ||
58 | }, &nv40_perfctr_func }, | ||
59 | { 0x20, (const struct nouveau_specsig[]) { | ||
60 | {} | ||
61 | }, &nv40_perfctr_func }, | ||
62 | { 0x20, (const struct nouveau_specsig[]) { | ||
63 | {} | ||
64 | }, &nv40_perfctr_func }, | ||
65 | {} | ||
66 | }; | ||
67 | |||
68 | struct nouveau_oclass * | ||
69 | nv84_perfmon_oclass = &(struct nv40_perfmon_oclass) { | ||
70 | .base.handle = NV_ENGINE(PERFMON, 0x84), | ||
71 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
72 | .ctor = nv40_perfmon_ctor, | ||
73 | .dtor = _nouveau_perfmon_dtor, | ||
74 | .init = _nouveau_perfmon_init, | ||
75 | .fini = _nouveau_perfmon_fini, | ||
76 | }, | ||
77 | .doms = nv84_perfmon, | ||
78 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c new file mode 100644 index 000000000000..6197ebdeb648 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nv40.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static const struct nouveau_specdom | ||
40 | nva3_perfmon[] = { | ||
41 | { 0x20, (const struct nouveau_specsig[]) { | ||
42 | {} | ||
43 | }, &nv40_perfctr_func }, | ||
44 | { 0x20, (const struct nouveau_specsig[]) { | ||
45 | {} | ||
46 | }, &nv40_perfctr_func }, | ||
47 | { 0x20, (const struct nouveau_specsig[]) { | ||
48 | {} | ||
49 | }, &nv40_perfctr_func }, | ||
50 | { 0x20, (const struct nouveau_specsig[]) { | ||
51 | {} | ||
52 | }, &nv40_perfctr_func }, | ||
53 | { 0x20, (const struct nouveau_specsig[]) { | ||
54 | {} | ||
55 | }, &nv40_perfctr_func }, | ||
56 | { 0x20, (const struct nouveau_specsig[]) { | ||
57 | {} | ||
58 | }, &nv40_perfctr_func }, | ||
59 | { 0x20, (const struct nouveau_specsig[]) { | ||
60 | {} | ||
61 | }, &nv40_perfctr_func }, | ||
62 | { 0x20, (const struct nouveau_specsig[]) { | ||
63 | {} | ||
64 | }, &nv40_perfctr_func }, | ||
65 | {} | ||
66 | }; | ||
67 | |||
68 | static int | ||
69 | nva3_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
70 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
71 | struct nouveau_object **object) | ||
72 | { | ||
73 | int ret = nv40_perfmon_ctor(parent, engine, oclass, data, size, object); | ||
74 | if (ret == 0) { | ||
75 | struct nv40_perfmon_priv *priv = (void *)*object; | ||
76 | ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, | ||
77 | nva3_perfmon_pwr); | ||
78 | if (ret) | ||
79 | return ret; | ||
80 | |||
81 | priv->base.last = 3; | ||
82 | } | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | struct nouveau_oclass * | ||
87 | nva3_perfmon_oclass = &(struct nv40_perfmon_oclass) { | ||
88 | .base.handle = NV_ENGINE(PERFMON, 0xa3), | ||
89 | .base.ofuncs = &(struct nouveau_ofuncs) { | ||
90 | .ctor = nva3_perfmon_ctor, | ||
91 | .dtor = _nouveau_perfmon_dtor, | ||
92 | .init = _nouveau_perfmon_init, | ||
93 | .fini = _nouveau_perfmon_fini, | ||
94 | }, | ||
95 | .doms = nva3_perfmon, | ||
96 | }.base; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c new file mode 100644 index 000000000000..74b241042502 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nvc0.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static const struct nouveau_specdom | ||
40 | nvc0_perfmon_hub[] = { | ||
41 | {} | ||
42 | }; | ||
43 | |||
44 | static const struct nouveau_specdom | ||
45 | nvc0_perfmon_gpc[] = { | ||
46 | {} | ||
47 | }; | ||
48 | |||
49 | static const struct nouveau_specdom | ||
50 | nvc0_perfmon_part[] = { | ||
51 | {} | ||
52 | }; | ||
53 | |||
54 | static void | ||
55 | nvc0_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, | ||
56 | struct nouveau_perfctr *ctr) | ||
57 | { | ||
58 | struct nvc0_perfmon_priv *priv = (void *)ppm; | ||
59 | struct nvc0_perfmon_cntr *cntr = (void *)ctr; | ||
60 | u32 log = ctr->logic_op; | ||
61 | u32 src = 0x00000000; | ||
62 | int i; | ||
63 | |||
64 | for (i = 0; i < 4 && ctr->signal[i]; i++) | ||
65 | src |= (ctr->signal[i] - dom->signal) << (i * 8); | ||
66 | |||
67 | nv_wr32(priv, dom->addr + 0x09c, 0x00040002); | ||
68 | nv_wr32(priv, dom->addr + 0x100, 0x00000000); | ||
69 | nv_wr32(priv, dom->addr + 0x040 + (cntr->base.slot * 0x08), src); | ||
70 | nv_wr32(priv, dom->addr + 0x044 + (cntr->base.slot * 0x08), log); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | nvc0_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, | ||
75 | struct nouveau_perfctr *ctr) | ||
76 | { | ||
77 | struct nvc0_perfmon_priv *priv = (void *)ppm; | ||
78 | struct nvc0_perfmon_cntr *cntr = (void *)ctr; | ||
79 | |||
80 | switch (cntr->base.slot) { | ||
81 | case 0: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x08c); break; | ||
82 | case 1: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x088); break; | ||
83 | case 2: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x080); break; | ||
84 | case 3: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x090); break; | ||
85 | } | ||
86 | cntr->base.clk = nv_rd32(priv, dom->addr + 0x070); | ||
87 | } | ||
88 | |||
89 | static void | ||
90 | nvc0_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom) | ||
91 | { | ||
92 | struct nvc0_perfmon_priv *priv = (void *)ppm; | ||
93 | nv_wr32(priv, dom->addr + 0x06c, dom->signal_nr - 0x40 + 0x27); | ||
94 | nv_wr32(priv, dom->addr + 0x0ec, 0x00000011); | ||
95 | } | ||
96 | |||
97 | const struct nouveau_funcdom | ||
98 | nvc0_perfctr_func = { | ||
99 | .init = nvc0_perfctr_init, | ||
100 | .read = nvc0_perfctr_read, | ||
101 | .next = nvc0_perfctr_next, | ||
102 | }; | ||
103 | |||
104 | int | ||
105 | nvc0_perfmon_fini(struct nouveau_object *object, bool suspend) | ||
106 | { | ||
107 | struct nvc0_perfmon_priv *priv = (void *)object; | ||
108 | nv_mask(priv, 0x000200, 0x10000000, 0x00000000); | ||
109 | nv_mask(priv, 0x000200, 0x10000000, 0x10000000); | ||
110 | return nouveau_perfmon_fini(&priv->base, suspend); | ||
111 | } | ||
112 | |||
113 | static int | ||
114 | nvc0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
115 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
116 | struct nouveau_object **pobject) | ||
117 | { | ||
118 | struct nvc0_perfmon_priv *priv; | ||
119 | u32 mask; | ||
120 | int ret; | ||
121 | |||
122 | ret = nouveau_perfmon_create(parent, engine, oclass, &priv); | ||
123 | *pobject = nv_object(priv); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
127 | ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, | ||
128 | nvc0_perfmon_pwr); | ||
129 | if (ret) | ||
130 | return ret; | ||
131 | |||
132 | /* HUB */ | ||
133 | ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200, | ||
134 | nvc0_perfmon_hub); | ||
135 | if (ret) | ||
136 | return ret; | ||
137 | |||
138 | /* GPC */ | ||
139 | mask = (1 << nv_rd32(priv, 0x022430)) - 1; | ||
140 | mask &= ~nv_rd32(priv, 0x022504); | ||
141 | mask &= ~nv_rd32(priv, 0x022584); | ||
142 | |||
143 | ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000, | ||
144 | 0x1000, 0x200, nvc0_perfmon_gpc); | ||
145 | if (ret) | ||
146 | return ret; | ||
147 | |||
148 | /* PART */ | ||
149 | mask = (1 << nv_rd32(priv, 0x022438)) - 1; | ||
150 | mask &= ~nv_rd32(priv, 0x022548); | ||
151 | mask &= ~nv_rd32(priv, 0x0225c8); | ||
152 | |||
153 | ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000, | ||
154 | 0x1000, 0x200, nvc0_perfmon_part); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | nv_engine(priv)->cclass = &nouveau_perfmon_cclass; | ||
159 | nv_engine(priv)->sclass = nouveau_perfmon_sclass; | ||
160 | priv->base.last = 7; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | struct nouveau_oclass | ||
165 | nvc0_perfmon_oclass = { | ||
166 | .handle = NV_ENGINE(PERFMON, 0xc0), | ||
167 | .ofuncs = &(struct nouveau_ofuncs) { | ||
168 | .ctor = nvc0_perfmon_ctor, | ||
169 | .dtor = _nouveau_perfmon_dtor, | ||
170 | .init = _nouveau_perfmon_init, | ||
171 | .fini = nvc0_perfmon_fini, | ||
172 | }, | ||
173 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h new file mode 100644 index 000000000000..f66bca484263 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef __NVKM_PM_NVC0_H__ | ||
2 | #define __NVKM_PM_NVC0_H__ | ||
3 | |||
4 | #include "priv.h" | ||
5 | |||
6 | struct nvc0_perfmon_priv { | ||
7 | struct nouveau_perfmon base; | ||
8 | }; | ||
9 | |||
10 | struct nvc0_perfmon_cntr { | ||
11 | struct nouveau_perfctr base; | ||
12 | }; | ||
13 | |||
14 | extern const struct nouveau_funcdom nvc0_perfctr_func; | ||
15 | int nvc0_perfmon_fini(struct nouveau_object *, bool); | ||
16 | |||
17 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c new file mode 100644 index 000000000000..71d718c12075 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nvc0.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static const struct nouveau_specdom | ||
40 | nve0_perfmon_hub[] = { | ||
41 | { 0x60, (const struct nouveau_specsig[]) { | ||
42 | { 0x47, "hub00_user_0" }, | ||
43 | {} | ||
44 | }, &nvc0_perfctr_func }, | ||
45 | { 0x40, (const struct nouveau_specsig[]) { | ||
46 | { 0x27, "hub01_user_0" }, | ||
47 | {} | ||
48 | }, &nvc0_perfctr_func }, | ||
49 | { 0x60, (const struct nouveau_specsig[]) { | ||
50 | { 0x47, "hub02_user_0" }, | ||
51 | {} | ||
52 | }, &nvc0_perfctr_func }, | ||
53 | { 0x60, (const struct nouveau_specsig[]) { | ||
54 | { 0x47, "hub03_user_0" }, | ||
55 | {} | ||
56 | }, &nvc0_perfctr_func }, | ||
57 | { 0x40, (const struct nouveau_specsig[]) { | ||
58 | { 0x03, "host_mmio_rd" }, | ||
59 | { 0x27, "hub04_user_0" }, | ||
60 | {} | ||
61 | }, &nvc0_perfctr_func }, | ||
62 | { 0x60, (const struct nouveau_specsig[]) { | ||
63 | { 0x47, "hub05_user_0" }, | ||
64 | {} | ||
65 | }, &nvc0_perfctr_func }, | ||
66 | { 0xc0, (const struct nouveau_specsig[]) { | ||
67 | { 0x74, "host_fb_rd3x" }, | ||
68 | { 0x75, "host_fb_rd3x_2" }, | ||
69 | { 0xa7, "hub06_user_0" }, | ||
70 | {} | ||
71 | }, &nvc0_perfctr_func }, | ||
72 | { 0x60, (const struct nouveau_specsig[]) { | ||
73 | { 0x47, "hub07_user_0" }, | ||
74 | {} | ||
75 | }, &nvc0_perfctr_func }, | ||
76 | {} | ||
77 | }; | ||
78 | |||
79 | static const struct nouveau_specdom | ||
80 | nve0_perfmon_gpc[] = { | ||
81 | { 0xe0, (const struct nouveau_specsig[]) { | ||
82 | { 0xc7, "gpc00_user_0" }, | ||
83 | {} | ||
84 | }, &nvc0_perfctr_func }, | ||
85 | {} | ||
86 | }; | ||
87 | |||
88 | static const struct nouveau_specdom | ||
89 | nve0_perfmon_part[] = { | ||
90 | { 0x60, (const struct nouveau_specsig[]) { | ||
91 | { 0x47, "part00_user_0" }, | ||
92 | {} | ||
93 | }, &nvc0_perfctr_func }, | ||
94 | { 0x60, (const struct nouveau_specsig[]) { | ||
95 | { 0x47, "part01_user_0" }, | ||
96 | {} | ||
97 | }, &nvc0_perfctr_func }, | ||
98 | {} | ||
99 | }; | ||
100 | |||
101 | static int | ||
102 | nve0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
103 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
104 | struct nouveau_object **pobject) | ||
105 | { | ||
106 | struct nvc0_perfmon_priv *priv; | ||
107 | u32 mask; | ||
108 | int ret; | ||
109 | |||
110 | ret = nouveau_perfmon_create(parent, engine, oclass, &priv); | ||
111 | *pobject = nv_object(priv); | ||
112 | if (ret) | ||
113 | return ret; | ||
114 | |||
115 | /* PDAEMON */ | ||
116 | ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, | ||
117 | nve0_perfmon_pwr); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | |||
121 | /* HUB */ | ||
122 | ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200, | ||
123 | nve0_perfmon_hub); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | |||
127 | /* GPC */ | ||
128 | mask = (1 << nv_rd32(priv, 0x022430)) - 1; | ||
129 | mask &= ~nv_rd32(priv, 0x022504); | ||
130 | mask &= ~nv_rd32(priv, 0x022584); | ||
131 | |||
132 | ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000, | ||
133 | 0x1000, 0x200, nve0_perfmon_gpc); | ||
134 | if (ret) | ||
135 | return ret; | ||
136 | |||
137 | /* PART */ | ||
138 | mask = (1 << nv_rd32(priv, 0x022438)) - 1; | ||
139 | mask &= ~nv_rd32(priv, 0x022548); | ||
140 | mask &= ~nv_rd32(priv, 0x0225c8); | ||
141 | |||
142 | ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000, | ||
143 | 0x1000, 0x200, nve0_perfmon_part); | ||
144 | if (ret) | ||
145 | return ret; | ||
146 | |||
147 | nv_engine(priv)->cclass = &nouveau_perfmon_cclass; | ||
148 | nv_engine(priv)->sclass = nouveau_perfmon_sclass; | ||
149 | priv->base.last = 7; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | struct nouveau_oclass | ||
154 | nve0_perfmon_oclass = { | ||
155 | .handle = NV_ENGINE(PERFMON, 0xe0), | ||
156 | .ofuncs = &(struct nouveau_ofuncs) { | ||
157 | .ctor = nve0_perfmon_ctor, | ||
158 | .dtor = _nouveau_perfmon_dtor, | ||
159 | .init = _nouveau_perfmon_init, | ||
160 | .fini = nvc0_perfmon_fini, | ||
161 | }, | ||
162 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c new file mode 100644 index 000000000000..47256f78a895 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include "nvc0.h" | ||
26 | |||
27 | /******************************************************************************* | ||
28 | * Perfmon object classes | ||
29 | ******************************************************************************/ | ||
30 | |||
31 | /******************************************************************************* | ||
32 | * PPM context | ||
33 | ******************************************************************************/ | ||
34 | |||
35 | /******************************************************************************* | ||
36 | * PPM engine/subdev functions | ||
37 | ******************************************************************************/ | ||
38 | |||
39 | static int | ||
40 | nvf0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | ||
41 | struct nouveau_oclass *oclass, void *data, u32 size, | ||
42 | struct nouveau_object **pobject) | ||
43 | { | ||
44 | struct nvc0_perfmon_priv *priv; | ||
45 | int ret; | ||
46 | |||
47 | ret = nouveau_perfmon_create(parent, engine, oclass, &priv); | ||
48 | *pobject = nv_object(priv); | ||
49 | if (ret) | ||
50 | return ret; | ||
51 | |||
52 | ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, | ||
53 | nve0_perfmon_pwr); | ||
54 | if (ret) | ||
55 | return ret; | ||
56 | |||
57 | nv_engine(priv)->cclass = &nouveau_perfmon_cclass; | ||
58 | nv_engine(priv)->sclass = nouveau_perfmon_sclass; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | struct nouveau_oclass | ||
63 | nvf0_perfmon_oclass = { | ||
64 | .handle = NV_ENGINE(PERFMON, 0xf0), | ||
65 | .ofuncs = &(struct nouveau_ofuncs) { | ||
66 | .ctor = nvf0_perfmon_ctor, | ||
67 | .dtor = _nouveau_perfmon_dtor, | ||
68 | .init = _nouveau_perfmon_init, | ||
69 | .fini = nvc0_perfmon_fini, | ||
70 | }, | ||
71 | }; | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h new file mode 100644 index 000000000000..0ac8714fe0ba --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h | |||
@@ -0,0 +1,91 @@ | |||
1 | #ifndef __NVKM_PERFMON_PRIV_H__ | ||
2 | #define __NVKM_PERFMON_PRIV_H__ | ||
3 | |||
4 | #include <engine/perfmon.h> | ||
5 | |||
6 | struct nouveau_perfctr { | ||
7 | struct nouveau_object base; | ||
8 | struct list_head head; | ||
9 | struct nouveau_perfsig *signal[4]; | ||
10 | int slot; | ||
11 | u32 logic_op; | ||
12 | u32 clk; | ||
13 | u32 ctr; | ||
14 | }; | ||
15 | |||
16 | extern struct nouveau_oclass nouveau_perfmon_sclass[]; | ||
17 | |||
18 | struct nouveau_perfctx { | ||
19 | struct nouveau_engctx base; | ||
20 | }; | ||
21 | |||
22 | extern struct nouveau_oclass nouveau_perfmon_cclass; | ||
23 | |||
24 | struct nouveau_specsig { | ||
25 | u8 signal; | ||
26 | const char *name; | ||
27 | }; | ||
28 | |||
29 | struct nouveau_perfsig { | ||
30 | const char *name; | ||
31 | }; | ||
32 | |||
33 | struct nouveau_perfdom; | ||
34 | struct nouveau_perfctr * | ||
35 | nouveau_perfsig_wrap(struct nouveau_perfmon *, const char *, | ||
36 | struct nouveau_perfdom **); | ||
37 | |||
38 | struct nouveau_specdom { | ||
39 | u16 signal_nr; | ||
40 | const struct nouveau_specsig *signal; | ||
41 | const struct nouveau_funcdom *func; | ||
42 | }; | ||
43 | |||
44 | extern const struct nouveau_specdom nva3_perfmon_pwr[]; | ||
45 | extern const struct nouveau_specdom nvc0_perfmon_pwr[]; | ||
46 | extern const struct nouveau_specdom nve0_perfmon_pwr[]; | ||
47 | |||
48 | struct nouveau_perfdom { | ||
49 | struct list_head head; | ||
50 | struct list_head list; | ||
51 | const struct nouveau_funcdom *func; | ||
52 | char name[32]; | ||
53 | u32 addr; | ||
54 | u8 quad; | ||
55 | u32 signal_nr; | ||
56 | struct nouveau_perfsig signal[]; | ||
57 | }; | ||
58 | |||
59 | struct nouveau_funcdom { | ||
60 | void (*init)(struct nouveau_perfmon *, struct nouveau_perfdom *, | ||
61 | struct nouveau_perfctr *); | ||
62 | void (*read)(struct nouveau_perfmon *, struct nouveau_perfdom *, | ||
63 | struct nouveau_perfctr *); | ||
64 | void (*next)(struct nouveau_perfmon *, struct nouveau_perfdom *); | ||
65 | }; | ||
66 | |||
67 | int nouveau_perfdom_new(struct nouveau_perfmon *, const char *, u32, | ||
68 | u32, u32, u32, const struct nouveau_specdom *); | ||
69 | |||
70 | #define nouveau_perfmon_create(p,e,o,d) \ | ||
71 | nouveau_perfmon_create_((p), (e), (o), sizeof(**d), (void **)d) | ||
72 | #define nouveau_perfmon_dtor(p) ({ \ | ||
73 | struct nouveau_perfmon *c = (p); \ | ||
74 | _nouveau_perfmon_dtor(nv_object(c)); \ | ||
75 | }) | ||
76 | #define nouveau_perfmon_init(p) ({ \ | ||
77 | struct nouveau_perfmon *c = (p); \ | ||
78 | _nouveau_perfmon_init(nv_object(c)); \ | ||
79 | }) | ||
80 | #define nouveau_perfmon_fini(p,s) ({ \ | ||
81 | struct nouveau_perfmon *c = (p); \ | ||
82 | _nouveau_perfmon_fini(nv_object(c), (s)); \ | ||
83 | }) | ||
84 | |||
85 | int nouveau_perfmon_create_(struct nouveau_object *, struct nouveau_object *, | ||
86 | struct nouveau_oclass *, int, void **); | ||
87 | void _nouveau_perfmon_dtor(struct nouveau_object *); | ||
88 | int _nouveau_perfmon_init(struct nouveau_object *); | ||
89 | int _nouveau_perfmon_fini(struct nouveau_object *, bool); | ||
90 | |||
91 | #endif | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index cf9e73c014ab..a30fd990afc8 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -98,6 +98,37 @@ struct nv_dma_class { | |||
98 | u32 conf0; | 98 | u32 conf0; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | /* Perfmon counter class | ||
102 | * | ||
103 | * XXXX: NV_PERFCTR | ||
104 | */ | ||
105 | #define NV_PERFCTR_CLASS 0x0000ffff | ||
106 | #define NV_PERFCTR_QUERY 0x00000000 | ||
107 | #define NV_PERFCTR_SAMPLE 0x00000001 | ||
108 | #define NV_PERFCTR_READ 0x00000002 | ||
109 | |||
110 | struct nv_perfctr_class { | ||
111 | u16 logic_op; | ||
112 | struct { | ||
113 | char __user *name; /*XXX: use cfu when exposed to userspace */ | ||
114 | u32 size; | ||
115 | } signal[4]; | ||
116 | }; | ||
117 | |||
118 | struct nv_perfctr_query { | ||
119 | u32 iter; | ||
120 | u32 size; | ||
121 | char __user *name; /*XXX: use ctu when exposed to userspace */ | ||
122 | }; | ||
123 | |||
124 | struct nv_perfctr_sample { | ||
125 | }; | ||
126 | |||
127 | struct nv_perfctr_read { | ||
128 | u32 ctr; | ||
129 | u32 clk; | ||
130 | }; | ||
131 | |||
101 | /* DMA FIFO channel classes | 132 | /* DMA FIFO channel classes |
102 | * | 133 | * |
103 | * 006b: NV03_CHANNEL_DMA | 134 | * 006b: NV03_CHANNEL_DMA |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h index 0709ed520eb2..ac2881d1776a 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/device.h +++ b/drivers/gpu/drm/nouveau/core/include/core/device.h | |||
@@ -54,6 +54,7 @@ enum nv_subdev_type { | |||
54 | NVDEV_ENGINE_VIC, | 54 | NVDEV_ENGINE_VIC, |
55 | NVDEV_ENGINE_VENC, | 55 | NVDEV_ENGINE_VENC, |
56 | NVDEV_ENGINE_DISP, | 56 | NVDEV_ENGINE_DISP, |
57 | NVDEV_ENGINE_PERFMON, | ||
57 | 58 | ||
58 | NVDEV_SUBDEV_NR, | 59 | NVDEV_SUBDEV_NR, |
59 | }; | 60 | }; |
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h b/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h new file mode 100644 index 000000000000..49b0024910fe --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h | |||
@@ -0,0 +1,39 @@ | |||
1 | #ifndef __NVKM_PERFMON_H__ | ||
2 | #define __NVKM_PERFMON_H__ | ||
3 | |||
4 | #include <core/device.h> | ||
5 | #include <core/engine.h> | ||
6 | #include <core/engctx.h> | ||
7 | #include <core/class.h> | ||
8 | |||
9 | struct nouveau_perfdom; | ||
10 | struct nouveau_perfctr; | ||
11 | struct nouveau_perfmon { | ||
12 | struct nouveau_engine base; | ||
13 | |||
14 | struct nouveau_perfctx *context; | ||
15 | void *profile_data; | ||
16 | |||
17 | struct list_head domains; | ||
18 | u32 sequence; | ||
19 | |||
20 | /*XXX: temp for daemon backend */ | ||
21 | u32 pwr[8]; | ||
22 | u32 last; | ||
23 | }; | ||
24 | |||
25 | static inline struct nouveau_perfmon * | ||
26 | nouveau_perfmon(void *obj) | ||
27 | { | ||
28 | return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_PERFMON]; | ||
29 | } | ||
30 | |||
31 | extern struct nouveau_oclass *nv40_perfmon_oclass; | ||
32 | extern struct nouveau_oclass *nv50_perfmon_oclass; | ||
33 | extern struct nouveau_oclass *nv84_perfmon_oclass; | ||
34 | extern struct nouveau_oclass *nva3_perfmon_oclass; | ||
35 | extern struct nouveau_oclass nvc0_perfmon_oclass; | ||
36 | extern struct nouveau_oclass nve0_perfmon_oclass; | ||
37 | extern struct nouveau_oclass nvf0_perfmon_oclass; | ||
38 | |||
39 | #endif | ||