Lines Matching full:crc

43  * DOC: CRC ABI
45 * DRM device drivers can provide to userspace CRC information of each frame as
46 * it reached a given hardware component (a CRC sampling "source").
49 * file dri/0/crtc-N/crc/control in debugfs, with N being the :ref:`index of
54 * Once frame CRC generation is enabled, userspace can capture them by reading
55 * the dri/0/crtc-N/crc/data file. Each line in that file contains the frame
57 * containing the CRC data. Fields are separated by a single space and the number
58 * of CRC fields is source-specific.
60 * Note that though in some cases the CRC is computed in a specified way and on
61 * the frame contents as supplied by userspace (eDP 1.3), in general the CRC
64 * rely on being able to generate matching CRC values for the frame contents that
70 * The debugfs files are automatically set up if those vfuncs are set. CRC samples
75 * CRC results must be reliable across non-full-modeset atomic commits, so if a
77 * CRC generation, then the driver must mark that commit as a full modeset
79 * consistent results, generic userspace must re-setup CRC generation after a
100 if (strcmp(sources[i], crtc->crc.source)) in crc_control_show()
109 seq_printf(m, "%s*\n", crtc->crc.source); in crc_control_show()
125 struct drm_crtc_crc *crc = &crtc->crc; in crc_control_write() local
134 DRM_DEBUG_KMS("Expected < %lu bytes into crtc crc control\n", in crc_control_write()
152 spin_lock_irq(&crc->lock); in crc_control_write()
154 if (crc->opened) { in crc_control_write()
155 spin_unlock_irq(&crc->lock); in crc_control_write()
160 kfree(crc->source); in crc_control_write()
161 crc->source = source; in crc_control_write()
163 spin_unlock_irq(&crc->lock); in crc_control_write()
178 static int crtc_crc_data_count(struct drm_crtc_crc *crc) in crtc_crc_data_count() argument
180 assert_spin_locked(&crc->lock); in crtc_crc_data_count()
181 return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR); in crtc_crc_data_count()
184 static void crtc_crc_cleanup(struct drm_crtc_crc *crc) in crtc_crc_cleanup() argument
186 kfree(crc->entries); in crtc_crc_cleanup()
187 crc->overflow = false; in crtc_crc_cleanup()
188 crc->entries = NULL; in crtc_crc_cleanup()
189 crc->head = 0; in crtc_crc_cleanup()
190 crc->tail = 0; in crtc_crc_cleanup()
191 crc->values_cnt = 0; in crtc_crc_cleanup()
192 crc->opened = false; in crtc_crc_cleanup()
198 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_open() local
216 ret = crtc->funcs->verify_crc_source(crtc, crc->source, &values_cnt); in crtc_crc_open()
230 spin_lock_irq(&crc->lock); in crtc_crc_open()
231 if (!crc->opened) { in crtc_crc_open()
232 crc->opened = true; in crtc_crc_open()
233 crc->entries = entries; in crtc_crc_open()
234 crc->values_cnt = values_cnt; in crtc_crc_open()
238 spin_unlock_irq(&crc->lock); in crtc_crc_open()
245 ret = crtc->funcs->set_crc_source(crtc, crc->source); in crtc_crc_open()
252 spin_lock_irq(&crc->lock); in crtc_crc_open()
253 crtc_crc_cleanup(crc); in crtc_crc_open()
254 spin_unlock_irq(&crc->lock); in crtc_crc_open()
261 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_release() local
264 spin_lock_irq(&crc->lock); in crtc_crc_release()
265 crc->opened = false; in crtc_crc_release()
266 spin_unlock_irq(&crc->lock); in crtc_crc_release()
270 spin_lock_irq(&crc->lock); in crtc_crc_release()
271 crtc_crc_cleanup(crc); in crtc_crc_release()
272 spin_unlock_irq(&crc->lock); in crtc_crc_release()
278 * 1 frame field of 10 chars plus a number of CRC fields of 10 chars each, space
288 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_read() local
293 spin_lock_irq(&crc->lock); in crtc_crc_read()
295 if (!crc->source) { in crtc_crc_read()
296 spin_unlock_irq(&crc->lock); in crtc_crc_read()
301 while (crtc_crc_data_count(crc) == 0) { in crtc_crc_read()
303 spin_unlock_irq(&crc->lock); in crtc_crc_read()
307 ret = wait_event_interruptible_lock_irq(crc->wq, in crtc_crc_read()
308 crtc_crc_data_count(crc), in crtc_crc_read()
309 crc->lock); in crtc_crc_read()
311 spin_unlock_irq(&crc->lock); in crtc_crc_read()
317 entry = &crc->entries[crc->tail]; in crtc_crc_read()
319 if (count < LINE_LEN(crc->values_cnt)) { in crtc_crc_read()
320 spin_unlock_irq(&crc->lock); in crtc_crc_read()
325 crc->tail = (crc->tail + 1) & (DRM_CRC_ENTRIES_NR - 1); in crtc_crc_read()
327 spin_unlock_irq(&crc->lock); in crtc_crc_read()
334 for (i = 0; i < crc->values_cnt; i++) in crtc_crc_read()
336 sprintf(buf + 10 + crc->values_cnt * 11, "\n"); in crtc_crc_read()
338 if (copy_to_user(user_buf, buf, LINE_LEN(crc->values_cnt))) in crtc_crc_read()
341 return LINE_LEN(crc->values_cnt); in crtc_crc_read()
347 struct drm_crtc_crc *crc = &crtc->crc; in crtc_crc_poll() local
350 poll_wait(file, &crc->wq, wait); in crtc_crc_poll()
352 spin_lock_irq(&crc->lock); in crtc_crc_poll()
353 if (crc->source && crtc_crc_data_count(crc)) in crtc_crc_poll()
355 spin_unlock_irq(&crc->lock); in crtc_crc_poll()
375 crc_ent = debugfs_create_dir("crc", crtc->debugfs_entry); in drm_debugfs_crtc_crc_add()
384 * drm_crtc_add_crc_entry - Add entry with CRC information for a frame
388 * @crcs: array of CRC values, with length matching #drm_crtc_crc.values_cnt
396 struct drm_crtc_crc *crc = &crtc->crc; in drm_crtc_add_crc_entry() local
401 spin_lock_irqsave(&crc->lock, flags); in drm_crtc_add_crc_entry()
404 if (!crc->entries) { in drm_crtc_add_crc_entry()
405 spin_unlock_irqrestore(&crc->lock, flags); in drm_crtc_add_crc_entry()
409 head = crc->head; in drm_crtc_add_crc_entry()
410 tail = crc->tail; in drm_crtc_add_crc_entry()
413 bool was_overflow = crc->overflow; in drm_crtc_add_crc_entry()
415 crc->overflow = true; in drm_crtc_add_crc_entry()
416 spin_unlock_irqrestore(&crc->lock, flags); in drm_crtc_add_crc_entry()
419 DRM_ERROR("Overflow of CRC buffer, userspace reads too slow.\n"); in drm_crtc_add_crc_entry()
424 entry = &crc->entries[head]; in drm_crtc_add_crc_entry()
427 memcpy(&entry->crcs, crcs, sizeof(*crcs) * crc->values_cnt); in drm_crtc_add_crc_entry()
430 crc->head = head; in drm_crtc_add_crc_entry()
432 spin_unlock_irqrestore(&crc->lock, flags); in drm_crtc_add_crc_entry()
434 wake_up_interruptible(&crc->wq); in drm_crtc_add_crc_entry()