1 /* SPDX-License-Identifier: MIT */ 2 #ifndef __NV50_CRC_H__ 3 #define __NV50_CRC_H__ 4 5 #include <linux/mutex.h> 6 #include <drm/drm_crtc.h> 7 #include <drm/drm_vblank_work.h> 8 9 #include <nvif/mem.h> 10 #include <nvkm/subdev/bios.h> 11 #include "nouveau_encoder.h" 12 13 struct nv50_atom; 14 struct nv50_disp; 15 struct nv50_head; 16 17 #if IS_ENABLED(CONFIG_DEBUG_FS) 18 enum nv50_crc_source { 19 NV50_CRC_SOURCE_NONE = 0, 20 NV50_CRC_SOURCE_AUTO, 21 NV50_CRC_SOURCE_RG, 22 NV50_CRC_SOURCE_OUTP_ACTIVE, 23 NV50_CRC_SOURCE_OUTP_COMPLETE, 24 NV50_CRC_SOURCE_OUTP_INACTIVE, 25 }; 26 27 /* RG -> SF (DP only) 28 * -> SOR 29 * -> PIOR 30 * -> DAC 31 */ 32 enum nv50_crc_source_type { 33 NV50_CRC_SOURCE_TYPE_NONE = 0, 34 NV50_CRC_SOURCE_TYPE_SOR, 35 NV50_CRC_SOURCE_TYPE_PIOR, 36 NV50_CRC_SOURCE_TYPE_DAC, 37 NV50_CRC_SOURCE_TYPE_RG, 38 NV50_CRC_SOURCE_TYPE_SF, 39 }; 40 41 struct nv50_crc_notifier_ctx { 42 struct nvif_mem mem; 43 struct nvif_object ntfy; 44 }; 45 46 struct nv50_crc_atom { 47 enum nv50_crc_source src; 48 /* Only used for gv100+ */ 49 u8 wndw : 4; 50 }; 51 52 struct nv50_crc_func { 53 int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type, 54 struct nv50_crc_notifier_ctx *, u32 wndw); 55 int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *); 56 u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *, 57 enum nv50_crc_source, int idx); 58 bool (*ctx_finished)(struct nv50_head *, 59 struct nv50_crc_notifier_ctx *); 60 short flip_threshold; 61 short num_entries; 62 size_t notifier_len; 63 }; 64 65 struct nv50_crc { 66 spinlock_t lock; 67 struct nv50_crc_notifier_ctx ctx[2]; 68 struct drm_vblank_work flip_work; 69 enum nv50_crc_source src; 70 71 u64 frame; 72 short entry_idx; 73 short flip_threshold; 74 u8 ctx_idx : 1; 75 bool ctx_changed : 1; 76 }; 77 78 void nv50_crc_init(struct drm_device *dev); 79 int nv50_head_crc_late_register(struct nv50_head *); 80 void nv50_crc_handle_vblank(struct nv50_head *head); 81 82 int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *); 83 const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *); 84 int nv50_crc_set_source(struct drm_crtc *, const char *); 85 86 int nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *, 87 struct nv50_head_atom *); 88 void nv50_crc_atomic_check_outp(struct nv50_atom *atom); 89 void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *); 90 void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *); 91 void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *); 92 void nv50_crc_atomic_start_reporting(struct drm_atomic_state *); 93 void nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *); 94 void nv50_crc_atomic_clr(struct nv50_head *); 95 96 extern const struct nv50_crc_func crc907d; 97 extern const struct nv50_crc_func crcc37d; 98 99 #else /* IS_ENABLED(CONFIG_DEBUG_FS) */ 100 struct nv50_crc {}; 101 struct nv50_crc_func {}; 102 struct nv50_crc_atom {}; 103 104 #define nv50_crc_verify_source NULL 105 #define nv50_crc_get_sources NULL 106 #define nv50_crc_set_source NULL 107 108 static inline void nv50_crc_init(struct drm_device *dev) {} 109 static inline int 110 nv50_head_crc_late_register(struct nv50_head *head) { return 0; } 111 static inline void nv50_crc_handle_vblank(struct nv50_head *head) {} 112 113 static inline int 114 nv50_crc_atomic_check_head(struct nv50_head *head, 115 struct nv50_head_atom *asyh, 116 struct nv50_head_atom *armh) { return 0; } 117 static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {} 118 static inline void 119 nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {} 120 static inline void 121 nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {} 122 static inline void 123 nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {} 124 static inline void 125 nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {} 126 static inline void 127 nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {} 128 static inline void 129 nv50_crc_atomic_clr(struct nv50_head *head) {} 130 131 #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ 132 #endif /* !__NV50_CRC_H__ */ 133