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