Lines Matching full:crc
36 * DOC: CRC ABI
38 * DRM device drivers can provide to userspace CRC information of each frame as
39 * it reached a given hardware component (a CRC sampling "source").
42 * file dri/0/crtc-N/crc/control in debugfs, with N being the index of the CRTC.
47 * Once frame CRC generation is enabled, userspace can capture them by reading
48 * the dri/0/crtc-N/crc/data file. Each line in that file contains the frame
50 * containing the CRC data. Fields are separated by a single space and the number
51 * of CRC fields is source-specific.
53 * Note that though in some cases the CRC is computed in a specified way and on
54 * the frame contents as supplied by userspace (eDP 1.3), in general the CRC
57 * rely on being able to generate matching CRC values for the frame contents that
63 * set up if that vfunc is set. CRC samples need to be captured in the driver by
71 seq_printf(m, "%s\n", crtc->crc.source); in crc_control_show()
88 struct drm_crtc_crc *crc = &crtc->crc; in crc_control_write() local
95 DRM_DEBUG_KMS("Expected < %lu bytes into crtc crc control\n", in crc_control_write()
107 spin_lock_irq(&crc->lock); in crc_control_write()
109 if (crc->opened) { in crc_control_write()
110 spin_unlock_irq(&crc->lock); in crc_control_write()
115 kfree(crc->source); in crc_control_write()
116 crc->source = source; in crc_control_write()
118 spin_unlock_irq(&crc->lock); in crc_control_write()
133 static int crtc_crc_data_count(struct drm_crtc_crc *crc) in crtc_crc_data_count() argument
135 assert_spin_locked(&crc->lock); in crtc_crc_data_count()
136 return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); in crtc_crc_data_count()
139 static void crtc_crc_cleanup(struct drm_crtc_crc *crc) in crtc_crc_cleanup() argument
141 kfree(crc->entries); in crtc_crc_cleanup()
142 crc->overflow = false; in crtc_crc_cleanup()
143 crc->entries = NULL; in crtc_crc_cleanup()
144 crc->head = 0; in crtc_crc_cleanup()
145 crc->tail = 0; in crtc_crc_cleanup()
146 crc->values_cnt = 0; in crtc_crc_cleanup()
147 crc->opened = false; in crtc_crc_cleanup()
153 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_open() local
171 spin_lock_irq(&crc->lock); in crtc_crc_open()
172 if (!crc->opened) in crtc_crc_open()
173 crc->opened = true; in crtc_crc_open()
176 spin_unlock_irq(&crc->lock); in crtc_crc_open()
181 ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt); in crtc_crc_open()
201 spin_lock_irq(&crc->lock); in crtc_crc_open()
202 crc->entries = entries; in crtc_crc_open()
203 crc->values_cnt = values_cnt; in crtc_crc_open()
210 ret = wait_event_interruptible_lock_irq(crc->wq, in crtc_crc_open()
211 crtc_crc_data_count(crc), in crtc_crc_open()
212 crc->lock); in crtc_crc_open()
213 spin_unlock_irq(&crc->lock); in crtc_crc_open()
223 spin_lock_irq(&crc->lock); in crtc_crc_open()
224 crtc_crc_cleanup(crc); in crtc_crc_open()
225 spin_unlock_irq(&crc->lock); in crtc_crc_open()
232 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_release() local
237 spin_lock_irq(&crc->lock); in crtc_crc_release()
238 crtc_crc_cleanup(crc); in crtc_crc_release()
239 spin_unlock_irq(&crc->lock); in crtc_crc_release()
245 * 1 frame field of 10 chars plus a number of CRC fields of 10 chars each, space
255 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_read() local
260 spin_lock_irq(&crc->lock); in crtc_crc_read()
262 if (!crc->source) { in crtc_crc_read()
263 spin_unlock_irq(&crc->lock); in crtc_crc_read()
268 while (crtc_crc_data_count(crc) == 0) { in crtc_crc_read()
270 spin_unlock_irq(&crc->lock); in crtc_crc_read()
274 ret = wait_event_interruptible_lock_irq(crc->wq, in crtc_crc_read()
275 crtc_crc_data_count(crc), in crtc_crc_read()
276 crc->lock); in crtc_crc_read()
278 spin_unlock_irq(&crc->lock); in crtc_crc_read()
284 entry = &crc->entries[crc->tail]; in crtc_crc_read()
286 if (count < LINE_LEN(crc->values_cnt)) { in crtc_crc_read()
287 spin_unlock_irq(&crc->lock); in crtc_crc_read()
292 crc->tail = (crc->tail + 1) & (DRM_CRC_ENTRIES_NR - 1); in crtc_crc_read()
294 spin_unlock_irq(&crc->lock); in crtc_crc_read()
301 for (i = 0; i < crc->values_cnt; i++) in crtc_crc_read()
303 sprintf(buf + 10 + crc->values_cnt * 11, "\n"); in crtc_crc_read()
305 if (copy_to_user(user_buf, buf, LINE_LEN(crc->values_cnt))) in crtc_crc_read()
308 return LINE_LEN(crc->values_cnt); in crtc_crc_read()
314 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_poll() local
317 poll_wait(file, &crc->wq, wait); in crtc_crc_poll()
319 spin_lock_irq(&crc->lock); in crtc_crc_poll()
320 if (crc->source && crtc_crc_data_count(crc)) in crtc_crc_poll()
324 spin_unlock_irq(&crc->lock); in crtc_crc_poll()
344 crc_ent = debugfs_create_dir("crc", crtc->debugfs_entry); in drm_debugfs_crtc_crc_add()
367 * drm_crtc_add_crc_entry - Add entry with CRC information for a frame
371 * @crcs: array of CRC values, with length matching #drm_crtc_crc.values_cnt
379 struct drm_crtc_crc *crc = &crtc->crc; in drm_crtc_add_crc_entry() local
384 spin_lock_irqsave(&crc->lock, flags); in drm_crtc_add_crc_entry()
387 if (!crc->entries) { in drm_crtc_add_crc_entry()
388 spin_unlock_irqrestore(&crc->lock, flags); in drm_crtc_add_crc_entry()
392 head = crc->head; in drm_crtc_add_crc_entry()
393 tail = crc->tail; in drm_crtc_add_crc_entry()
396 bool was_overflow = crc->overflow; in drm_crtc_add_crc_entry()
398 crc->overflow = true; in drm_crtc_add_crc_entry()
399 spin_unlock_irqrestore(&crc->lock, flags); in drm_crtc_add_crc_entry()
402 DRM_ERROR("Overflow of CRC buffer, userspace reads too slow.\n"); in drm_crtc_add_crc_entry()
407 entry = &crc->entries[head]; in drm_crtc_add_crc_entry()
410 memcpy(&entry->crcs, crcs, sizeof(*crcs) * crc->values_cnt); in drm_crtc_add_crc_entry()
413 crc->head = head; in drm_crtc_add_crc_entry()
415 spin_unlock_irqrestore(&crc->lock, flags); in drm_crtc_add_crc_entry()
417 wake_up_interruptible(&crc->wq); in drm_crtc_add_crc_entry()