summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/dispnv50/crc.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/dispnv50/crc.h')
-rw-r--r--drivers/gpu/drm/nouveau/dispnv50/crc.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/crc.h b/drivers/gpu/drm/nouveau/dispnv50/crc.h
new file mode 100644
index 000000000000..4fce871b04c8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/dispnv50/crc.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NV50_CRC_H__
+#define __NV50_CRC_H__
+
+#include <linux/mutex.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_vblank_work.h>
+
+#include <nvif/mem.h>
+#include <nvkm/subdev/bios.h>
+#include "nouveau_encoder.h"
+
+struct nv50_atom;
+struct nv50_disp;
+struct nv50_head;
+
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+enum nv50_crc_source {
+ NV50_CRC_SOURCE_NONE = 0,
+ NV50_CRC_SOURCE_AUTO,
+ NV50_CRC_SOURCE_RG,
+ NV50_CRC_SOURCE_OUTP_ACTIVE,
+ NV50_CRC_SOURCE_OUTP_COMPLETE,
+ NV50_CRC_SOURCE_OUTP_INACTIVE,
+};
+
+/* RG -> SF (DP only)
+ * -> SOR
+ * -> PIOR
+ * -> DAC
+ */
+enum nv50_crc_source_type {
+ NV50_CRC_SOURCE_TYPE_NONE = 0,
+ NV50_CRC_SOURCE_TYPE_SOR,
+ NV50_CRC_SOURCE_TYPE_PIOR,
+ NV50_CRC_SOURCE_TYPE_DAC,
+ NV50_CRC_SOURCE_TYPE_RG,
+ NV50_CRC_SOURCE_TYPE_SF,
+};
+
+struct nv50_crc_notifier_ctx {
+ struct nvif_mem mem;
+ struct nvif_object ntfy;
+};
+
+struct nv50_crc_atom {
+ enum nv50_crc_source src;
+ /* Only used for gv100+ */
+ u8 wndw : 4;
+};
+
+struct nv50_crc_func {
+ int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type,
+ struct nv50_crc_notifier_ctx *, u32 wndw);
+ int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
+ u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,
+ enum nv50_crc_source, int idx);
+ bool (*ctx_finished)(struct nv50_head *,
+ struct nv50_crc_notifier_ctx *);
+ short flip_threshold;
+ short num_entries;
+ size_t notifier_len;
+};
+
+struct nv50_crc {
+ spinlock_t lock;
+ struct nv50_crc_notifier_ctx ctx[2];
+ struct drm_vblank_work flip_work;
+ enum nv50_crc_source src;
+
+ u64 frame;
+ short entry_idx;
+ short flip_threshold;
+ u8 ctx_idx : 1;
+ bool ctx_changed : 1;
+};
+
+void nv50_crc_init(struct drm_device *dev);
+int nv50_head_crc_late_register(struct nv50_head *);
+void nv50_crc_handle_vblank(struct nv50_head *head);
+
+int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *);
+const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *);
+int nv50_crc_set_source(struct drm_crtc *, const char *);
+
+int nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
+ struct nv50_head_atom *);
+void nv50_crc_atomic_check_outp(struct nv50_atom *atom);
+void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *);
+void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *);
+void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *);
+void nv50_crc_atomic_start_reporting(struct drm_atomic_state *);
+void nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *);
+void nv50_crc_atomic_clr(struct nv50_head *);
+
+extern const struct nv50_crc_func crc907d;
+extern const struct nv50_crc_func crcc37d;
+
+#else /* IS_ENABLED(CONFIG_DEBUG_FS) */
+struct nv50_crc {};
+struct nv50_crc_func {};
+struct nv50_crc_atom {};
+
+#define nv50_crc_verify_source NULL
+#define nv50_crc_get_sources NULL
+#define nv50_crc_set_source NULL
+
+static inline void nv50_crc_init(struct drm_device *dev) {}
+static inline int
+nv50_head_crc_late_register(struct nv50_head *head) { return 0; }
+static inline void nv50_crc_handle_vblank(struct nv50_head *head) {}
+
+static inline int
+nv50_crc_atomic_check_head(struct nv50_head *head,
+ struct nv50_head_atom *asyh,
+ struct nv50_head_atom *armh) { return 0; }
+static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {}
+static inline void
+nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {}
+static inline void
+nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {}
+static inline void
+nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {}
+static inline void
+nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {}
+static inline void
+nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {}
+static inline void
+nv50_crc_atomic_clr(struct nv50_head *head) {}
+
+#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
+#endif /* !__NV50_CRC_H__ */