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
23static 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
32static 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
49int
50nv50_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
65const 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
71static void
72nv50_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
83static 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
123static 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
128static void
129nv50_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
154void 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
216out:
217	spin_unlock(&crc->lock);
218}
219
220static 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
240void 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
272void 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
294void 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
319void 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
351int 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
381void 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
428static enum nv50_crc_source_type
429nv50_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
450void 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
472void 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
480static inline int
481nv50_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 */
501static inline int
502nv50_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
528fail_fini:
529	nvif_mem_dtor(&ctx->mem);
530	return ret;
531}
532
533static inline void
534nv50_crc_ctx_fini(struct nv50_crc_notifier_ctx *ctx)
535{
536	nvif_object_dtor(&ctx->ntfy);
537	nvif_mem_dtor(&ctx->mem);
538}
539
540int 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
582retry:
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
609out_drop_locks:
610	drm_modeset_drop_locks(&ctx);
611out_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);
617out_acquire_fini:
618	drm_modeset_acquire_fini(&ctx);
619	return ret;
620
621deadlock:
622	drm_atomic_state_clear(state);
623	drm_modeset_backoff(&ctx);
624	goto retry;
625}
626
627static int
628nv50_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
645static int
646nv50_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
652static ssize_t
653nv50_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
694out:
695	drm_modeset_unlock(&crtc->mutex);
696	return ret;
697}
698
699static 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
707int 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
724static inline void
725nv50_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
736void 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