0001
0002 #ifndef __NV50_CRC_H__
0003 #define __NV50_CRC_H__
0004
0005 #include <linux/mutex.h>
0006 #include <drm/drm_crtc.h>
0007 #include <drm/drm_vblank_work.h>
0008
0009 #include <nvif/mem.h>
0010 #include <nvkm/subdev/bios.h>
0011 #include "nouveau_encoder.h"
0012
0013 struct nv50_atom;
0014 struct nv50_disp;
0015 struct nv50_head;
0016
0017 #if IS_ENABLED(CONFIG_DEBUG_FS)
0018 enum nv50_crc_source {
0019 NV50_CRC_SOURCE_NONE = 0,
0020 NV50_CRC_SOURCE_AUTO,
0021 NV50_CRC_SOURCE_RG,
0022 NV50_CRC_SOURCE_OUTP_ACTIVE,
0023 NV50_CRC_SOURCE_OUTP_COMPLETE,
0024 NV50_CRC_SOURCE_OUTP_INACTIVE,
0025 };
0026
0027
0028
0029
0030
0031
0032 enum nv50_crc_source_type {
0033 NV50_CRC_SOURCE_TYPE_NONE = 0,
0034 NV50_CRC_SOURCE_TYPE_SOR,
0035 NV50_CRC_SOURCE_TYPE_PIOR,
0036 NV50_CRC_SOURCE_TYPE_DAC,
0037 NV50_CRC_SOURCE_TYPE_RG,
0038 NV50_CRC_SOURCE_TYPE_SF,
0039 };
0040
0041 struct nv50_crc_notifier_ctx {
0042 struct nvif_mem mem;
0043 struct nvif_object ntfy;
0044 };
0045
0046 struct nv50_crc_atom {
0047 enum nv50_crc_source src;
0048 };
0049
0050 struct nv50_crc_func {
0051 int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type type,
0052 struct nv50_crc_notifier_ctx *ctx);
0053 int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
0054 u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,
0055 enum nv50_crc_source, int idx);
0056 bool (*ctx_finished)(struct nv50_head *,
0057 struct nv50_crc_notifier_ctx *);
0058 short flip_threshold;
0059 short num_entries;
0060 size_t notifier_len;
0061 };
0062
0063 struct nv50_crc {
0064 spinlock_t lock;
0065 struct nv50_crc_notifier_ctx ctx[2];
0066 struct drm_vblank_work flip_work;
0067 enum nv50_crc_source src;
0068
0069 u64 frame;
0070 short entry_idx;
0071 short flip_threshold;
0072 u8 ctx_idx : 1;
0073 bool ctx_changed : 1;
0074 };
0075
0076 void nv50_crc_init(struct drm_device *dev);
0077 int nv50_head_crc_late_register(struct nv50_head *);
0078 void nv50_crc_handle_vblank(struct nv50_head *head);
0079
0080 int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *);
0081 const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *);
0082 int nv50_crc_set_source(struct drm_crtc *, const char *);
0083
0084 int nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
0085 struct nv50_head_atom *);
0086 void nv50_crc_atomic_check_outp(struct nv50_atom *atom);
0087 void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *);
0088 void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *);
0089 void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *);
0090 void nv50_crc_atomic_start_reporting(struct drm_atomic_state *);
0091 void nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *);
0092 void nv50_crc_atomic_clr(struct nv50_head *);
0093
0094 extern const struct nv50_crc_func crc907d;
0095 extern const struct nv50_crc_func crcc37d;
0096 extern const struct nv50_crc_func crcc57d;
0097
0098 #else
0099 struct nv50_crc {};
0100 struct nv50_crc_func {};
0101 struct nv50_crc_atom {};
0102
0103 #define nv50_crc_verify_source NULL
0104 #define nv50_crc_get_sources NULL
0105 #define nv50_crc_set_source NULL
0106
0107 static inline void nv50_crc_init(struct drm_device *dev) {}
0108 static inline int
0109 nv50_head_crc_late_register(struct nv50_head *head) { return 0; }
0110 static inline void nv50_crc_handle_vblank(struct nv50_head *head) {}
0111
0112 static inline int
0113 nv50_crc_atomic_check_head(struct nv50_head *head,
0114 struct nv50_head_atom *asyh,
0115 struct nv50_head_atom *armh) { return 0; }
0116 static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {}
0117 static inline void
0118 nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {}
0119 static inline void
0120 nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {}
0121 static inline void
0122 nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {}
0123 static inline void
0124 nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {}
0125 static inline void
0126 nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {}
0127 static inline void
0128 nv50_crc_atomic_clr(struct nv50_head *head) {}
0129
0130 #endif
0131 #endif