This is not complete documentation, but covers the pieces I read through
while reviewing the IGT CRC tests for nouveau. It covers the
nouveau-specific debugfs file, an overview of why the code is more
complicated than the DRM display CRC support documentation would lead
one to expect, and the nv50_crc_func vtable. Many of the details were
gleaned from Lyude's commit message, but I think it's valuable to have
them with the code rather than in the change log.

The rendered documentation of the functions in nv50_crc_func aren't as
nice as I'd like, but from what I can tell it would require creating a
typedef for each function with proper argument/return value docs.

Cc: Lyude Paul <ly...@redhat.com>
Signed-off-by: Jeremy Cline <jcl...@redhat.com>
---
 drivers/gpu/drm/nouveau/dispnv50/crc.c |  8 ++++
 drivers/gpu/drm/nouveau/dispnv50/crc.h | 65 ++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.c 
b/drivers/gpu/drm/nouveau/dispnv50/crc.c
index b8c31b697797..84df41e8fb05 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/crc.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/crc.c
@@ -699,6 +699,14 @@ nv50_crc_debugfs_flip_threshold_set(struct file *file,
        return ret;
 }
 
+/**
+ * DOC: nv_crc/flip_threshold
+ *
+ * The number of CRC entries to place in a :term:`CRC notifier context` before
+ * attempting to flip to the other notifier context. Writing ``-1`` to this 
file
+ * will reset the threshold to the default value, which is hardware-dependent.
+ * Values cannot be greater than the default or less than ``-1``.
+ */
 static const struct file_operations nv50_crc_flip_threshold_fops = {
        .owner = THIS_MODULE,
        .open = nv50_crc_debugfs_flip_threshold_open,
diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.h 
b/drivers/gpu/drm/nouveau/dispnv50/crc.h
index 4fce871b04c8..04ebb1f936db 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/crc.h
+++ b/drivers/gpu/drm/nouveau/dispnv50/crc.h
@@ -10,6 +10,24 @@
 #include <nvkm/subdev/bios.h>
 #include "nouveau_encoder.h"
 
+/**
+ * DOC: Overview
+ *
+ * This interface is designed to aid in the implementation of the standard DRM
+ * CRC interface that is part of :doc:`drm-uapi`. NVIDIA's hardware has a
+ * peculiar CRC implementation that limits the number of CRCs that can be
+ * captured, which breaks the DRM API's expectations.
+ *
+ * CRCs are reported to a :term:`CRC notifier context` of limited size. Once 
the
+ * context fills, an overflow bit is set and no further CRCs are reported. To
+ * work around this, the driver flips between notifier contexts to allow users
+ * to capture an arbitrary number of CRCs.
+ *
+ * .. warning:: The flip requires flushing two separate updates on the
+ *     :term:`EVO/NVD` channel, and this results in the unavoidable loss of a 
single
+ *     frame's CRC.
+ */
+
 struct nv50_atom;
 struct nv50_disp;
 struct nv50_head;
@@ -49,16 +67,63 @@ struct nv50_crc_atom {
        u8 wndw : 4;
 };
 
+/**
+ * struct nv50_crc_func - Functions and data for CRC support
+ *
+ * The interface used to abstract CRC support across card families that support
+ * it.
+ */
 struct nv50_crc_func {
+       /**
+        * @set_src: Program the hardware to capture CRCs from the given
+        * &enum nv50_crc_source_type. Using NULL for the source and ctx will
+        * disable CRC for the given &struct nv50_head.
+        *
+        * Return 0 on success, or a negative error code.
+        */
        int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type,
                       struct nv50_crc_notifier_ctx *, u32 wndw);
+
+       /**
+        * @set_ctx: Change the &struct nv50_crc_notifier_ctx used to capture
+        * CRC entries. Providing a NULL context will remove any existing
+        * context.
+        *
+        * Return 0 on success, or a negative error code.
+        */
        int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
+
+       /**
+        * @get_entry: Read the CRC entry at the given index. idx is guaranteed
+        * to be less than @num_entries so implementations do not need to
+        * perform a bounds check.
+        *
+        * Return the CRC or 0 if there is no CRC for the given index.
+        */
        u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,
                         enum nv50_crc_source, int idx);
+
+       /**
+        * @ctx_finished: Return true when all requested CRCs have been written
+        * and it is safe to read them.
+        */
        bool (*ctx_finished)(struct nv50_head *,
                             struct nv50_crc_notifier_ctx *);
+
+       /**
+        * @flip_threshold: The default number of CRC entries at which point the
+        * notifier context should be flipped. This should be set somewhat lower
+        * than @num_entries. It is configurable from userspace via DebugFS.
+        */
        short flip_threshold;
+
+       /**
+        * @num_entries: The maximum number of entries supported in the
+        * notifier context.
+        */
        short num_entries;
+
+       /** @notifier_len: The size of the notifier context in bytes. */
        size_t notifier_len;
 };
 
-- 
2.28.0

_______________________________________________
Nouveau mailing list
Nouveau@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to