112885ecbSLyude Paul /* SPDX-License-Identifier: MIT */
212885ecbSLyude Paul #ifndef __NV50_CRC_H__
312885ecbSLyude Paul #define __NV50_CRC_H__
412885ecbSLyude Paul 
512885ecbSLyude Paul #include <linux/mutex.h>
612885ecbSLyude Paul #include <drm/drm_crtc.h>
712885ecbSLyude Paul #include <drm/drm_vblank_work.h>
812885ecbSLyude Paul 
912885ecbSLyude Paul #include <nvif/mem.h>
1012885ecbSLyude Paul #include <nvkm/subdev/bios.h>
1112885ecbSLyude Paul #include "nouveau_encoder.h"
1212885ecbSLyude Paul 
1312885ecbSLyude Paul struct nv50_disp;
1412885ecbSLyude Paul struct nv50_head;
1512885ecbSLyude Paul 
1612885ecbSLyude Paul #if IS_ENABLED(CONFIG_DEBUG_FS)
1712885ecbSLyude Paul enum nv50_crc_source {
1812885ecbSLyude Paul 	NV50_CRC_SOURCE_NONE = 0,
1912885ecbSLyude Paul 	NV50_CRC_SOURCE_AUTO,
2012885ecbSLyude Paul 	NV50_CRC_SOURCE_RG,
2112885ecbSLyude Paul 	NV50_CRC_SOURCE_OUTP_ACTIVE,
2212885ecbSLyude Paul 	NV50_CRC_SOURCE_OUTP_COMPLETE,
2312885ecbSLyude Paul 	NV50_CRC_SOURCE_OUTP_INACTIVE,
2412885ecbSLyude Paul };
2512885ecbSLyude Paul 
2612885ecbSLyude Paul /* RG -> SF (DP only)
2712885ecbSLyude Paul  *    -> SOR
2812885ecbSLyude Paul  *    -> PIOR
2912885ecbSLyude Paul  *    -> DAC
3012885ecbSLyude Paul  */
3112885ecbSLyude Paul enum nv50_crc_source_type {
3212885ecbSLyude Paul 	NV50_CRC_SOURCE_TYPE_NONE = 0,
3312885ecbSLyude Paul 	NV50_CRC_SOURCE_TYPE_SOR,
3412885ecbSLyude Paul 	NV50_CRC_SOURCE_TYPE_PIOR,
3512885ecbSLyude Paul 	NV50_CRC_SOURCE_TYPE_DAC,
3612885ecbSLyude Paul 	NV50_CRC_SOURCE_TYPE_RG,
3712885ecbSLyude Paul 	NV50_CRC_SOURCE_TYPE_SF,
3812885ecbSLyude Paul };
3912885ecbSLyude Paul 
4012885ecbSLyude Paul struct nv50_crc_notifier_ctx {
4112885ecbSLyude Paul 	struct nvif_mem mem;
4212885ecbSLyude Paul 	struct nvif_object ntfy;
4312885ecbSLyude Paul };
4412885ecbSLyude Paul 
4512885ecbSLyude Paul struct nv50_crc_atom {
4612885ecbSLyude Paul 	enum nv50_crc_source src;
4712885ecbSLyude Paul 	/* Only used for gv100+ */
4812885ecbSLyude Paul 	u8 wndw : 4;
4912885ecbSLyude Paul };
5012885ecbSLyude Paul 
5112885ecbSLyude Paul struct nv50_crc_func {
5212885ecbSLyude Paul 	void (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type,
5312885ecbSLyude Paul 			struct nv50_crc_notifier_ctx *, u32 wndw);
5412885ecbSLyude Paul 	void (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
5512885ecbSLyude Paul 	u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,
5612885ecbSLyude Paul 			 enum nv50_crc_source, int idx);
5712885ecbSLyude Paul 	bool (*ctx_finished)(struct nv50_head *,
5812885ecbSLyude Paul 			     struct nv50_crc_notifier_ctx *);
5912885ecbSLyude Paul 	short flip_threshold;
6012885ecbSLyude Paul 	short num_entries;
6112885ecbSLyude Paul 	size_t notifier_len;
6212885ecbSLyude Paul };
6312885ecbSLyude Paul 
6412885ecbSLyude Paul struct nv50_crc {
6512885ecbSLyude Paul 	spinlock_t lock;
6612885ecbSLyude Paul 	struct nv50_crc_notifier_ctx ctx[2];
6712885ecbSLyude Paul 	struct drm_vblank_work flip_work;
6812885ecbSLyude Paul 	enum nv50_crc_source src;
6912885ecbSLyude Paul 
7012885ecbSLyude Paul 	u64 frame;
7112885ecbSLyude Paul 	short entry_idx;
7212885ecbSLyude Paul 	short flip_threshold;
7312885ecbSLyude Paul 	u8 ctx_idx : 1;
7412885ecbSLyude Paul 	bool ctx_changed : 1;
7512885ecbSLyude Paul };
7612885ecbSLyude Paul 
7712885ecbSLyude Paul void nv50_crc_init(struct drm_device *dev);
7812885ecbSLyude Paul int nv50_head_crc_late_register(struct nv50_head *);
7912885ecbSLyude Paul void nv50_crc_handle_vblank(struct nv50_head *head);
8012885ecbSLyude Paul 
8112885ecbSLyude Paul int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *);
8212885ecbSLyude Paul const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *);
8312885ecbSLyude Paul int nv50_crc_set_source(struct drm_crtc *, const char *);
8412885ecbSLyude Paul 
8512885ecbSLyude Paul int nv50_crc_atomic_check(struct nv50_head *, struct nv50_head_atom *,
8612885ecbSLyude Paul 			  struct nv50_head_atom *);
8712885ecbSLyude Paul void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *);
8812885ecbSLyude Paul void nv50_crc_atomic_prepare_notifier_contexts(struct drm_atomic_state *);
8912885ecbSLyude Paul void nv50_crc_atomic_start_reporting(struct drm_atomic_state *);
9012885ecbSLyude Paul void nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *);
9112885ecbSLyude Paul void nv50_crc_atomic_clr(struct nv50_head *);
9212885ecbSLyude Paul 
9312885ecbSLyude Paul extern const struct nv50_crc_func crc907d;
9412885ecbSLyude Paul extern const struct nv50_crc_func crcc37d;
9512885ecbSLyude Paul 
9612885ecbSLyude Paul #else /* IS_ENABLED(CONFIG_DEBUG_FS) */
9712885ecbSLyude Paul struct nv50_crc {};
9812885ecbSLyude Paul struct nv50_crc_func {};
9912885ecbSLyude Paul struct nv50_crc_atom {};
10012885ecbSLyude Paul 
10112885ecbSLyude Paul #define nv50_crc_verify_source NULL
10212885ecbSLyude Paul #define nv50_crc_get_sources NULL
10312885ecbSLyude Paul #define nv50_crc_set_source NULL
10412885ecbSLyude Paul 
10512885ecbSLyude Paul static inline void nv50_crc_init(struct drm_device *dev) {}
10612885ecbSLyude Paul static inline int nv50_head_crc_late_register(struct nv50_head *) {}
10712885ecbSLyude Paul static inline void
10812885ecbSLyude Paul nv50_crc_handle_vblank(struct nv50_head *head) { return 0; }
10912885ecbSLyude Paul 
11012885ecbSLyude Paul static inline int
11112885ecbSLyude Paul nv50_crc_atomic_check(struct nv50_head *, struct nv50_head_atom *,
11212885ecbSLyude Paul 		      struct nv50_head_atom *) {}
11312885ecbSLyude Paul static inline void
11412885ecbSLyude Paul nv50_crc_atomic_stop_reporting(struct drm_atomic_state *) {}
11512885ecbSLyude Paul static inline void
11612885ecbSLyude Paul nv50_crc_atomic_prepare_notifier_contexts(struct drm_atomic_state *) {}
11712885ecbSLyude Paul static inline void
11812885ecbSLyude Paul nv50_crc_atomic_start_reporting(struct drm_atomic_state *) {}
11912885ecbSLyude Paul static inline void
12012885ecbSLyude Paul nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *) {}
12112885ecbSLyude Paul static inline void
12212885ecbSLyude Paul nv50_crc_atomic_clr(struct nv50_head *) {}
12312885ecbSLyude Paul 
12412885ecbSLyude Paul #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
12512885ecbSLyude Paul #endif /* !__NV50_CRC_H__ */
126