1 // SPDX-License-Identifier: MIT
2 #include <linux/debugfs.h>
3 #include <linux/string.h>
4
5 #include <drm/drm_crtc.h>
6 #include <drm/drm_atomic_helper.h>
7 #include <drm/drm_vblank.h>
8 #include <drm/drm_vblank_work.h>
9
10 #include <nvif/class.h>
11 #include <nvif/cl0002.h>
12 #include <nvif/timer.h>
13
14 #include <nvhw/class/cl907d.h>
15
16 #include "nouveau_drv.h"
17 #include "core.h"
18 #include "head.h"
19 #include "wndw.h"
20 #include "handles.h"
21 #include "crc.h"
22
23 static const char * const nv50_crc_sources[] = {
24 [NV50_CRC_SOURCE_NONE] = "none",
25 [NV50_CRC_SOURCE_AUTO] = "auto",
26 [NV50_CRC_SOURCE_RG] = "rg",
27 [NV50_CRC_SOURCE_OUTP_ACTIVE] = "outp-active",
28 [NV50_CRC_SOURCE_OUTP_COMPLETE] = "outp-complete",
29 [NV50_CRC_SOURCE_OUTP_INACTIVE] = "outp-inactive",
30 };
31
nv50_crc_parse_source(const char * buf,enum nv50_crc_source * s)32 static int nv50_crc_parse_source(const char *buf, enum nv50_crc_source *s)
33 {
34 int i;
35
36 if (!buf) {
37 *s = NV50_CRC_SOURCE_NONE;
38 return 0;
39 }
40
41 i = match_string(nv50_crc_sources, ARRAY_SIZE(nv50_crc_sources), buf);
42 if (i < 0)
43 return i;
44
45 *s = i;
46 return 0;
47 }
48
49 int
nv50_crc_verify_source(struct drm_crtc * crtc,const char * source_name,size_t * values_cnt)50 nv50_crc_verify_source(struct drm_crtc *crtc, const char *source_name,
51 size_t *values_cnt)
52 {
53 struct nouveau_drm *drm = nouveau_drm(crtc->dev);
54 enum nv50_crc_source source;
55
56 if (nv50_crc_parse_source(source_name, &source) < 0) {
57 NV_DEBUG(drm, "unknown source %s\n", source_name);
58 return -EINVAL;
59 }
60
61 *values_cnt = 1;
62 return 0;
63 }
64
nv50_crc_get_sources(struct drm_crtc * crtc,size_t * count)65 const char *const *nv50_crc_get_sources(struct drm_crtc *crtc, size_t *count)
66 {
67 *count = ARRAY_SIZE(nv50_crc_sources);
68 return nv50_crc_sources;
69 }
70
71 static void
nv50_crc_program_ctx(struct nv50_head * head,struct nv50_crc_notifier_ctx * ctx)72 nv50_crc_program_ctx(struct nv50_head *head,
73 struct nv50_crc_notifier_ctx *ctx)
74 {
75 struct nv50_disp *disp = nv50_disp(head->base.base.dev);
76 struct nv50_core *core = disp->core;
77 u32 interlock[NV50_DISP_INTERLOCK__SIZE] = { 0 };
78
79 core->func->crc->set_ctx(head, ctx);
80 core->func->update(core, interlock, false);
81 }
82
nv50_crc_ctx_flip_work(struct kthread_work * base)83 static void nv50_crc_ctx_flip_work(struct kthread_work *base)
84 {
85 struct drm_vblank_work *work = to_drm_vblank_work(base);
86 struct nv50_crc *crc = container_of(work, struct nv50_crc, flip_work);
87 struct nv50_head *head = container_of(crc, struct nv50_head, crc);
88 struct drm_crtc *crtc = &head->base.base;
89 struct drm_device *dev = crtc->dev;
90 struct nv50_disp *disp = nv50_disp(dev);
91 const uint64_t start_vbl = drm_crtc_vblank_count(crtc);
92 uint64_t end_vbl;
93 u8 new_idx = crc->ctx_idx ^ 1;
94
95 /*
96 * We don't want to accidentally wait for longer then the vblank, so
97 * try again for the next vblank if we don't grab the lock
98 */
99 if (!mutex_trylock(&disp->mutex)) {
100 drm_dbg_kms(dev, "Lock contended, delaying CRC ctx flip for %s\n", crtc->name);
101 drm_vblank_work_schedule(work, start_vbl + 1, true);
102 return;
103 }
104
105 drm_dbg_kms(dev, "Flipping notifier ctx for %s (%d -> %d)\n",
106 crtc->name, crc->ctx_idx, new_idx);
107
108 nv50_crc_program_ctx(head, NULL);
109 nv50_crc_program_ctx(head, &crc->ctx[new_idx]);
110 mutex_unlock(&disp->mutex);
111
112 end_vbl = drm_crtc_vblank_count(crtc);
113 if (unlikely(end_vbl != start_vbl))
114 NV_ERROR(nouveau_drm(dev),
115 "Failed to flip CRC context on %s on time (%llu > %llu)\n",
116 crtc->name, end_vbl, start_vbl);
117
118 spin_lock_irq(&crc->lock);
119 crc->ctx_changed = true;
120 spin_unlock_irq(&crc->lock);
121 }
122
nv50_crc_reset_ctx(struct nv50_crc_notifier_ctx * ctx)123 static inline void nv50_crc_reset_ctx(struct nv50_crc_notifier_ctx *ctx)
124 {
125 memset_io(ctx->mem.object.map.ptr, 0, ctx->mem.object.map.size);
126 }
127
128 static void
nv50_crc_get_entries(struct nv50_head * head,const struct nv50_crc_func * func,enum nv50_crc_source source)129 nv50_crc_get_entries(struct nv50_head *head,
130 const struct nv50_crc_func *func,
131 enum nv50_crc_source source)
132 {
133 struct drm_crtc *crtc = &head->base.base;
134 struct nv50_crc *crc = &head->crc;
135 u32 output_crc;
136
137 while (crc->entry_idx < func->num_entries) {
138 /*
139 * While Nvidia's documentation says CRCs are written on each
140 * subsequent vblank after being enabled, in practice they
141 * aren't written immediately.
142 */
143 output_crc = func->get_entry(head, &crc->ctx[crc->ctx_idx],
144 source, crc->entry_idx);
145 if (!output_crc)
146 return;
147
148 drm_crtc_add_crc_entry(crtc, true, crc->frame, &output_crc);
149 crc->frame++;
150 crc->entry_idx++;
151 }
152 }
153
nv50_crc_handle_vblank(struct nv50_head * head)154 void nv50_crc_handle_vblank(struct nv50_head *head)
155 {
156 struct drm_crtc *crtc = &head->base.base;
157 struct nv50_crc *crc = &head->crc;
158 const struct nv50_crc_func *func =
159 nv50_disp(head->base.base.dev)->core->func->crc;
160 struct nv50_crc_notifier_ctx *ctx;
161 bool need_reschedule = false;
162
163 if (!func)
164 return;
165
166 /*
167 * We don't lose events if we aren't able to report CRCs until the
168 * next vblank, so only report CRCs if the locks we need aren't
169 * contended to prevent missing an actual vblank event
170 */
171 if (!spin_trylock(&crc->lock))
172 return;
173
174 if (!crc->src)
175 goto out;
176
177 ctx = &crc->ctx[crc->ctx_idx];
178 if (crc->ctx_changed && func->ctx_finished(head, ctx)) {
179 nv50_crc_get_entries(head, func, crc->src);
180
181 crc->ctx_idx ^= 1;
182 crc->entry_idx = 0;
183 crc->ctx_changed = false;
184
185 /*
186 * Unfortunately when notifier contexts are changed during CRC
187 * capture, we will inevitably lose the CRC entry for the
188 * frame where the hardware actually latched onto the first
189 * UPDATE. According to Nvidia's hardware engineers, there's
190 * no workaround for this.
191 *
192 * Now, we could try to be smart here and calculate the number
193 * of missed CRCs based on audit timestamps, but those were
194 * removed starting with volta. Since we always flush our
195 * updates back-to-back without waiting, we'll just be
196 * optimistic and assume we always miss exactly one frame.
197 */
198 drm_dbg_kms(head->base.base.dev,
199 "Notifier ctx flip for head-%d finished, lost CRC for frame %llu\n",
200 head->base.index, crc->frame);
201 crc->frame++;
202
203 nv50_crc_reset_ctx(ctx);
204 need_reschedule = true;
205 }
206
207 nv50_crc_get_entries(head, func, crc->src);
208
209 if (need_reschedule)
210 drm_vblank_work_schedule(&crc->flip_work,
211 drm_crtc_vblank_count(crtc)
212 + crc->flip_threshold
213 - crc->entry_idx,
214 true);
215
216 out:
217 spin_unlock(&crc->lock);
218 }
219
nv50_crc_wait_ctx_finished(struct nv50_head * head,const struct nv50_crc_func * func,struct nv50_crc_notifier_ctx * ctx)220 static void nv50_crc_wait_ctx_finished(struct nv50_head *head,
221 const struct nv50_crc_func *func,
222 struct nv50_crc_notifier_ctx *ctx)
223 {
224 struct drm_device *dev = head->base.base.dev;
225 struct nouveau_drm *drm = nouveau_drm(dev);
226 s64 ret;
227
228 ret = nvif_msec(&drm->client.device, 50,
229 if (func->ctx_finished(head, ctx)) break;);
230 if (ret == -ETIMEDOUT)
231 NV_ERROR(drm,
232 "CRC notifier ctx for head %d not finished after 50ms\n",
233 head->base.index);
234 else if (ret)
235 NV_ATOMIC(drm,
236 "CRC notifier ctx for head-%d finished after %lldns\n",
237 head->base.index, ret);
238 }
239
nv50_crc_atomic_stop_reporting(struct drm_atomic_state * state)240 void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state)
241 {
242 struct drm_crtc_state *crtc_state;
243 struct drm_crtc *crtc;
244 int i;
245
246 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
247 struct nv50_head *head = nv50_head(crtc);
248 struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
249 struct nv50_crc *crc = &head->crc;
250
251 if (!asyh->clr.crc)
252 continue;
253
254 spin_lock_irq(&crc->lock);
255 crc->src = NV50_CRC_SOURCE_NONE;
256 spin_unlock_irq(&crc->lock);
257
258 drm_crtc_vblank_put(crtc);
259 drm_vblank_work_cancel_sync(&crc->flip_work);
260
261 NV_ATOMIC(nouveau_drm(crtc->dev),
262 "CRC reporting on vblank for head-%d disabled\n",
263 head->base.index);
264
265 /* CRC generation is still enabled in hw, we'll just report
266 * any remaining CRC entries ourselves after it gets disabled
267 * in hardware
268 */
269 }
270 }
271
nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state * state)272 void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state)
273 {
274 struct drm_crtc_state *new_crtc_state;
275 struct drm_crtc *crtc;
276 int i;
277
278 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
279 struct nv50_head *head = nv50_head(crtc);
280 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
281 struct nv50_crc *crc = &head->crc;
282 int i;
283
284 if (!asyh->set.crc)
285 continue;
286
287 crc->entry_idx = 0;
288 crc->ctx_changed = false;
289 for (i = 0; i < ARRAY_SIZE(crc->ctx); i++)
290 nv50_crc_reset_ctx(&crc->ctx[i]);
291 }
292 }
293
nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state * state)294 void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state)
295 {
296 const struct nv50_crc_func *func =
297 nv50_disp(state->dev)->core->func->crc;
298 struct drm_crtc_state *new_crtc_state;
299 struct drm_crtc *crtc;
300 int i;
301
302 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
303 struct nv50_head *head = nv50_head(crtc);
304 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
305 struct nv50_crc *crc = &head->crc;
306 struct nv50_crc_notifier_ctx *ctx = &crc->ctx[crc->ctx_idx];
307
308 if (!asyh->clr.crc)
309 continue;
310
311 if (crc->ctx_changed) {
312 nv50_crc_wait_ctx_finished(head, func, ctx);
313 ctx = &crc->ctx[crc->ctx_idx ^ 1];
314 }
315 nv50_crc_wait_ctx_finished(head, func, ctx);
316 }
317 }
318
nv50_crc_atomic_start_reporting(struct drm_atomic_state * state)319 void nv50_crc_atomic_start_reporting(struct drm_atomic_state *state)
320 {
321 struct drm_crtc_state *crtc_state;
322 struct drm_crtc *crtc;
323 int i;
324
325 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
326 struct nv50_head *head = nv50_head(crtc);
327 struct nv50_head_atom *asyh = nv50_head_atom(crtc_state);
328 struct nv50_crc *crc = &head->crc;
329 u64 vbl_count;
330
331 if (!asyh->set.crc)
332 continue;
333
334 drm_crtc_vblank_get(crtc);
335
336 spin_lock_irq(&crc->lock);
337 vbl_count = drm_crtc_vblank_count(crtc);
338 crc->frame = vbl_count;
339 crc->src = asyh->crc.src;
340 drm_vblank_work_schedule(&crc->flip_work,
341 vbl_count + crc->flip_threshold,
342 true);
343 spin_unlock_irq(&crc->lock);
344
345 NV_ATOMIC(nouveau_drm(crtc->dev),
346 "CRC reporting on vblank for head-%d enabled\n",
347 head->base.index);
348 }
349 }
350
nv50_crc_atomic_check_head(struct nv50_head * head,struct nv50_head_atom * asyh,struct nv50_head_atom * armh)351 int nv50_crc_atomic_check_head(struct nv50_head *head,
352 struct nv50_head_atom *asyh,
353 struct nv50_head_atom *armh)
354 {
355 struct nv50_atom *atom = nv50_atom(asyh->state.state);
356 bool changed = armh->crc.src != asyh->crc.src;
357
358 if (!armh->crc.src && !asyh->crc.src) {
359 asyh->set.crc = false;
360 asyh->clr.crc = false;
361 return 0;
362 }
363
364 if (drm_atomic_crtc_needs_modeset(&asyh->state) || changed) {
365 asyh->clr.crc = armh->crc.src && armh->state.active;
366 asyh->set.crc = asyh->crc.src && asyh->state.active;
367 if (changed)
368 asyh->set.or |= armh->or.crc_raster !=
369 asyh->or.crc_raster;
370
371 if (asyh->clr.crc && asyh->set.crc)
372 atom->flush_disable = true;
373 } else {
374 asyh->set.crc = false;
375 asyh->clr.crc = false;
376 }
377
378 return 0;
379 }
380
nv50_crc_atomic_check_outp(struct nv50_atom * atom)381 void nv50_crc_atomic_check_outp(struct nv50_atom *atom)
382 {
383 struct drm_crtc *crtc;
384 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
385 int i;
386
387 if (atom->flush_disable)
388 return;
389
390 for_each_oldnew_crtc_in_state(&atom->state, crtc, old_crtc_state,
391 new_crtc_state, i) {
392 struct nv50_head_atom *armh = nv50_head_atom(old_crtc_state);
393 struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
394 struct nv50_outp_atom *outp_atom;
395 struct nouveau_encoder *outp;
396 struct drm_encoder *encoder, *enc;
397
398 enc = nv50_head_atom_get_encoder(armh);
399 if (!enc)
400 continue;
401
402 outp = nv50_real_outp(enc);
403 if (!outp)
404 continue;
405
406 encoder = &outp->base.base;
407
408 if (!asyh->clr.crc)
409 continue;
410
411 /*
412 * Re-programming ORs can't be done in the same flush as
413 * disabling CRCs
414 */
415 list_for_each_entry(outp_atom, &atom->outp, head) {
416 if (outp_atom->encoder == encoder) {
417 if (outp_atom->set.mask) {
418 atom->flush_disable = true;
419 return;
420 } else {
421 break;
422 }
423 }
424 }
425 }
426 }
427
428 static enum nv50_crc_source_type
nv50_crc_source_type(struct nouveau_encoder * outp,enum nv50_crc_source source)429 nv50_crc_source_type(struct nouveau_encoder *outp,
430 enum nv50_crc_source source)
431 {
432 struct dcb_output *dcbe = outp->dcb;
433
434 switch (source) {
435 case NV50_CRC_SOURCE_NONE: return NV50_CRC_SOURCE_TYPE_NONE;
436 case NV50_CRC_SOURCE_RG: return NV50_CRC_SOURCE_TYPE_RG;
437 default: break;
438 }
439
440 if (dcbe->location != DCB_LOC_ON_CHIP)
441 return NV50_CRC_SOURCE_TYPE_PIOR;
442
443 switch (dcbe->type) {
444 case DCB_OUTPUT_DP: return NV50_CRC_SOURCE_TYPE_SF;
445 case DCB_OUTPUT_ANALOG: return NV50_CRC_SOURCE_TYPE_DAC;
446 default: return NV50_CRC_SOURCE_TYPE_SOR;
447 }
448 }
449
nv50_crc_atomic_set(struct nv50_head * head,struct nv50_head_atom * asyh)450 void nv50_crc_atomic_set(struct nv50_head *head,
451 struct nv50_head_atom *asyh)
452 {
453 struct drm_crtc *crtc = &head->base.base;
454 struct drm_device *dev = crtc->dev;
455 struct nv50_crc *crc = &head->crc;
456 const struct nv50_crc_func *func = nv50_disp(dev)->core->func->crc;
457 struct nouveau_encoder *outp;
458 struct drm_encoder *encoder;
459
460 encoder = nv50_head_atom_get_encoder(asyh);
461 if (!encoder)
462 return;
463
464 outp = nv50_real_outp(encoder);
465 if (!outp)
466 return;
467
468 func->set_src(head, outp->outp.or.id, nv50_crc_source_type(outp, asyh->crc.src),
469 &crc->ctx[crc->ctx_idx]);
470 }
471
nv50_crc_atomic_clr(struct nv50_head * head)472 void nv50_crc_atomic_clr(struct nv50_head *head)
473 {
474 const struct nv50_crc_func *func =
475 nv50_disp(head->base.base.dev)->core->func->crc;
476
477 func->set_src(head, 0, NV50_CRC_SOURCE_TYPE_NONE, NULL);
478 }
479
480 static inline int
nv50_crc_raster_type(enum nv50_crc_source source)481 nv50_crc_raster_type(enum nv50_crc_source source)
482 {
483 switch (source) {
484 case NV50_CRC_SOURCE_NONE:
485 case NV50_CRC_SOURCE_AUTO:
486 case NV50_CRC_SOURCE_RG:
487 case NV50_CRC_SOURCE_OUTP_ACTIVE:
488 return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_ACTIVE_RASTER;
489 case NV50_CRC_SOURCE_OUTP_COMPLETE:
490 return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_COMPLETE_RASTER;
491 case NV50_CRC_SOURCE_OUTP_INACTIVE:
492 return NV907D_HEAD_SET_CONTROL_OUTPUT_RESOURCE_CRC_MODE_NON_ACTIVE_RASTER;
493 }
494
495 return 0;
496 }
497
498 /* We handle mapping the memory for CRC notifiers ourselves, since each
499 * notifier needs it's own handle
500 */
501 static inline int
nv50_crc_ctx_init(struct nv50_head * head,struct nvif_mmu * mmu,struct nv50_crc_notifier_ctx * ctx,size_t len,int idx)502 nv50_crc_ctx_init(struct nv50_head *head, struct nvif_mmu *mmu,
503 struct nv50_crc_notifier_ctx *ctx, size_t len, int idx)
504 {
505 struct nv50_core *core = nv50_disp(head->base.base.dev)->core;
506 int ret;
507
508 ret = nvif_mem_ctor_map(mmu, "kmsCrcNtfy", NVIF_MEM_VRAM, len, &ctx->mem);
509 if (ret)
510 return ret;
511
512 ret = nvif_object_ctor(&core->chan.base.user, "kmsCrcNtfyCtxDma",
513 NV50_DISP_HANDLE_CRC_CTX(head, idx),
514 NV_DMA_IN_MEMORY,
515 &(struct nv_dma_v0) {
516 .target = NV_DMA_V0_TARGET_VRAM,
517 .access = NV_DMA_V0_ACCESS_RDWR,
518 .start = ctx->mem.addr,
519 .limit = ctx->mem.addr
520 + ctx->mem.size - 1,
521 }, sizeof(struct nv_dma_v0),
522 &ctx->ntfy);
523 if (ret)
524 goto fail_fini;
525
526 return 0;
527
528 fail_fini:
529 nvif_mem_dtor(&ctx->mem);
530 return ret;
531 }
532
533 static inline void
nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx * ctx)534 nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx)
535 {
536 nvif_object_dtor(&ctx->ntfy);
537 nvif_mem_dtor(&ctx->mem);
538 }
539
nv50_crc_set_source(struct drm_crtc * crtc,const char * source_str)540 int nv50_crc_set_source(struct drm_crtc *crtc, const char *source_str)
541 {
542 struct drm_device *dev = crtc->dev;
543 struct drm_atomic_state *state;
544 struct drm_modeset_acquire_ctx ctx;
545 struct nv50_head *head = nv50_head(crtc);
546 struct nv50_crc *crc = &head->crc;
547 const struct nv50_crc_func *func = nv50_disp(dev)->core->func->crc;
548 struct nvif_mmu *mmu = &nouveau_drm(dev)->client.mmu;
549 struct nv50_head_atom *asyh;
550 struct drm_crtc_state *crtc_state;
551 enum nv50_crc_source source;
552 int ret = 0, ctx_flags = 0, i;
553
554 ret = nv50_crc_parse_source(source_str, &source);
555 if (ret)
556 return ret;
557
558 /*
559 * Since we don't want the user to accidentally interrupt us as we're
560 * disabling CRCs
561 */
562 if (source)
563 ctx_flags |= DRM_MODESET_ACQUIRE_INTERRUPTIBLE;
564 drm_modeset_acquire_init(&ctx, ctx_flags);
565
566 state = drm_atomic_state_alloc(dev);
567 if (!state) {
568 ret = -ENOMEM;
569 goto out_acquire_fini;
570 }
571 state->acquire_ctx = &ctx;
572
573 if (source) {
574 for (i = 0; i < ARRAY_SIZE(head->crc.ctx); i++) {
575 ret = nv50_crc_ctx_init(head, mmu, &crc->ctx[i],
576 func->notifier_len, i);
577 if (ret)
578 goto out_ctx_fini;
579 }
580 }
581
582 retry:
583 crtc_state = drm_atomic_get_crtc_state(state, &head->base.base);
584 if (IS_ERR(crtc_state)) {
585 ret = PTR_ERR(crtc_state);
586 if (ret == -EDEADLK)
587 goto deadlock;
588 else if (ret)
589 goto out_drop_locks;
590 }
591 asyh = nv50_head_atom(crtc_state);
592 asyh->crc.src = source;
593 asyh->or.crc_raster = nv50_crc_raster_type(source);
594
595 ret = drm_atomic_commit(state);
596 if (ret == -EDEADLK)
597 goto deadlock;
598 else if (ret)
599 goto out_drop_locks;
600
601 if (!source) {
602 /*
603 * If the user specified a custom flip threshold through
604 * debugfs, reset it
605 */
606 crc->flip_threshold = func->flip_threshold;
607 }
608
609 out_drop_locks:
610 drm_modeset_drop_locks(&ctx);
611 out_ctx_fini:
612 if (!source || ret) {
613 for (i = 0; i < ARRAY_SIZE(crc->ctx); i++)
614 nv50_crc_ctx_fini(&crc->ctx[i]);
615 }
616 drm_atomic_state_put(state);
617 out_acquire_fini:
618 drm_modeset_acquire_fini(&ctx);
619 return ret;
620
621 deadlock:
622 drm_atomic_state_clear(state);
623 drm_modeset_backoff(&ctx);
624 goto retry;
625 }
626
627 static int
nv50_crc_debugfs_flip_threshold_get(struct seq_file * m,void * data)628 nv50_crc_debugfs_flip_threshold_get(struct seq_file *m, void *data)
629 {
630 struct nv50_head *head = m->private;
631 struct drm_crtc *crtc = &head->base.base;
632 struct nv50_crc *crc = &head->crc;
633 int ret;
634
635 ret = drm_modeset_lock_single_interruptible(&crtc->mutex);
636 if (ret)
637 return ret;
638
639 seq_printf(m, "%d\n", crc->flip_threshold);
640
641 drm_modeset_unlock(&crtc->mutex);
642 return ret;
643 }
644
645 static int
nv50_crc_debugfs_flip_threshold_open(struct inode * inode,struct file * file)646 nv50_crc_debugfs_flip_threshold_open(struct inode *inode, struct file *file)
647 {
648 return single_open(file, nv50_crc_debugfs_flip_threshold_get,
649 inode->i_private);
650 }
651
652 static ssize_t
nv50_crc_debugfs_flip_threshold_set(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)653 nv50_crc_debugfs_flip_threshold_set(struct file *file,
654 const char __user *ubuf, size_t len,
655 loff_t *offp)
656 {
657 struct seq_file *m = file->private_data;
658 struct nv50_head *head = m->private;
659 struct nv50_head_atom *armh;
660 struct drm_crtc *crtc = &head->base.base;
661 struct nouveau_drm *drm = nouveau_drm(crtc->dev);
662 struct nv50_crc *crc = &head->crc;
663 const struct nv50_crc_func *func =
664 nv50_disp(crtc->dev)->core->func->crc;
665 int value, ret;
666
667 ret = kstrtoint_from_user(ubuf, len, 10, &value);
668 if (ret)
669 return ret;
670
671 if (value > func->flip_threshold)
672 return -EINVAL;
673 else if (value == -1)
674 value = func->flip_threshold;
675 else if (value < -1)
676 return -EINVAL;
677
678 ret = drm_modeset_lock_single_interruptible(&crtc->mutex);
679 if (ret)
680 return ret;
681
682 armh = nv50_head_atom(crtc->state);
683 if (armh->crc.src) {
684 ret = -EBUSY;
685 goto out;
686 }
687
688 NV_DEBUG(drm,
689 "Changing CRC flip threshold for next capture on head-%d to %d\n",
690 head->base.index, value);
691 crc->flip_threshold = value;
692 ret = len;
693
694 out:
695 drm_modeset_unlock(&crtc->mutex);
696 return ret;
697 }
698
699 static const struct file_operations nv50_crc_flip_threshold_fops = {
700 .owner = THIS_MODULE,
701 .open = nv50_crc_debugfs_flip_threshold_open,
702 .read = seq_read,
703 .write = nv50_crc_debugfs_flip_threshold_set,
704 .release = single_release,
705 };
706
nv50_head_crc_late_register(struct nv50_head * head)707 int nv50_head_crc_late_register(struct nv50_head *head)
708 {
709 struct drm_crtc *crtc = &head->base.base;
710 const struct nv50_crc_func *func =
711 nv50_disp(crtc->dev)->core->func->crc;
712 struct dentry *root;
713
714 if (!func || !crtc->debugfs_entry)
715 return 0;
716
717 root = debugfs_create_dir("nv_crc", crtc->debugfs_entry);
718 debugfs_create_file("flip_threshold", 0644, root, head,
719 &nv50_crc_flip_threshold_fops);
720
721 return 0;
722 }
723
724 static inline void
nv50_crc_init_head(struct nv50_disp * disp,const struct nv50_crc_func * func,struct nv50_head * head)725 nv50_crc_init_head(struct nv50_disp *disp, const struct nv50_crc_func *func,
726 struct nv50_head *head)
727 {
728 struct nv50_crc *crc = &head->crc;
729
730 crc->flip_threshold = func->flip_threshold;
731 spin_lock_init(&crc->lock);
732 drm_vblank_work_init(&crc->flip_work, &head->base.base,
733 nv50_crc_ctx_flip_work);
734 }
735
nv50_crc_init(struct drm_device * dev)736 void nv50_crc_init(struct drm_device *dev)
737 {
738 struct nv50_disp *disp = nv50_disp(dev);
739 struct drm_crtc *crtc;
740 const struct nv50_crc_func *func = disp->core->func->crc;
741
742 if (!func)
743 return;
744
745 drm_for_each_crtc(crtc, dev)
746 nv50_crc_init_head(disp, func, nv50_head(crtc));
747 }
748