18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: MIT */ 28c2ecf20Sopenharmony_ci#ifndef __NV50_CRC_H__ 38c2ecf20Sopenharmony_ci#define __NV50_CRC_H__ 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/mutex.h> 68c2ecf20Sopenharmony_ci#include <drm/drm_crtc.h> 78c2ecf20Sopenharmony_ci#include <drm/drm_vblank_work.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <nvif/mem.h> 108c2ecf20Sopenharmony_ci#include <nvkm/subdev/bios.h> 118c2ecf20Sopenharmony_ci#include "nouveau_encoder.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistruct nv50_atom; 148c2ecf20Sopenharmony_cistruct nv50_disp; 158c2ecf20Sopenharmony_cistruct nv50_head; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_DEBUG_FS) 188c2ecf20Sopenharmony_cienum nv50_crc_source { 198c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_NONE = 0, 208c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_AUTO, 218c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_RG, 228c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_OUTP_ACTIVE, 238c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_OUTP_COMPLETE, 248c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_OUTP_INACTIVE, 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* RG -> SF (DP only) 288c2ecf20Sopenharmony_ci * -> SOR 298c2ecf20Sopenharmony_ci * -> PIOR 308c2ecf20Sopenharmony_ci * -> DAC 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_cienum nv50_crc_source_type { 338c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_TYPE_NONE = 0, 348c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_TYPE_SOR, 358c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_TYPE_PIOR, 368c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_TYPE_DAC, 378c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_TYPE_RG, 388c2ecf20Sopenharmony_ci NV50_CRC_SOURCE_TYPE_SF, 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistruct nv50_crc_notifier_ctx { 428c2ecf20Sopenharmony_ci struct nvif_mem mem; 438c2ecf20Sopenharmony_ci struct nvif_object ntfy; 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistruct nv50_crc_atom { 478c2ecf20Sopenharmony_ci enum nv50_crc_source src; 488c2ecf20Sopenharmony_ci /* Only used for gv100+ */ 498c2ecf20Sopenharmony_ci u8 wndw : 4; 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistruct nv50_crc_func { 538c2ecf20Sopenharmony_ci int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type, 548c2ecf20Sopenharmony_ci struct nv50_crc_notifier_ctx *, u32 wndw); 558c2ecf20Sopenharmony_ci int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *); 568c2ecf20Sopenharmony_ci u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *, 578c2ecf20Sopenharmony_ci enum nv50_crc_source, int idx); 588c2ecf20Sopenharmony_ci bool (*ctx_finished)(struct nv50_head *, 598c2ecf20Sopenharmony_ci struct nv50_crc_notifier_ctx *); 608c2ecf20Sopenharmony_ci short flip_threshold; 618c2ecf20Sopenharmony_ci short num_entries; 628c2ecf20Sopenharmony_ci size_t notifier_len; 638c2ecf20Sopenharmony_ci}; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistruct nv50_crc { 668c2ecf20Sopenharmony_ci spinlock_t lock; 678c2ecf20Sopenharmony_ci struct nv50_crc_notifier_ctx ctx[2]; 688c2ecf20Sopenharmony_ci struct drm_vblank_work flip_work; 698c2ecf20Sopenharmony_ci enum nv50_crc_source src; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci u64 frame; 728c2ecf20Sopenharmony_ci short entry_idx; 738c2ecf20Sopenharmony_ci short flip_threshold; 748c2ecf20Sopenharmony_ci u8 ctx_idx : 1; 758c2ecf20Sopenharmony_ci bool ctx_changed : 1; 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_civoid nv50_crc_init(struct drm_device *dev); 798c2ecf20Sopenharmony_ciint nv50_head_crc_late_register(struct nv50_head *); 808c2ecf20Sopenharmony_civoid nv50_crc_handle_vblank(struct nv50_head *head); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ciint nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *); 838c2ecf20Sopenharmony_ciconst char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *); 848c2ecf20Sopenharmony_ciint nv50_crc_set_source(struct drm_crtc *, const char *); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ciint nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *, 878c2ecf20Sopenharmony_ci struct nv50_head_atom *); 888c2ecf20Sopenharmony_civoid nv50_crc_atomic_check_outp(struct nv50_atom *atom); 898c2ecf20Sopenharmony_civoid nv50_crc_atomic_stop_reporting(struct drm_atomic_state *); 908c2ecf20Sopenharmony_civoid nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *); 918c2ecf20Sopenharmony_civoid nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *); 928c2ecf20Sopenharmony_civoid nv50_crc_atomic_start_reporting(struct drm_atomic_state *); 938c2ecf20Sopenharmony_civoid nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *); 948c2ecf20Sopenharmony_civoid nv50_crc_atomic_clr(struct nv50_head *); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ciextern const struct nv50_crc_func crc907d; 978c2ecf20Sopenharmony_ciextern const struct nv50_crc_func crcc37d; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci#else /* IS_ENABLED(CONFIG_DEBUG_FS) */ 1008c2ecf20Sopenharmony_cistruct nv50_crc {}; 1018c2ecf20Sopenharmony_cistruct nv50_crc_func {}; 1028c2ecf20Sopenharmony_cistruct nv50_crc_atom {}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci#define nv50_crc_verify_source NULL 1058c2ecf20Sopenharmony_ci#define nv50_crc_get_sources NULL 1068c2ecf20Sopenharmony_ci#define nv50_crc_set_source NULL 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic inline void nv50_crc_init(struct drm_device *dev) {} 1098c2ecf20Sopenharmony_cistatic inline int 1108c2ecf20Sopenharmony_cinv50_head_crc_late_register(struct nv50_head *head) { return 0; } 1118c2ecf20Sopenharmony_cistatic inline void nv50_crc_handle_vblank(struct nv50_head *head) {} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic inline int 1148c2ecf20Sopenharmony_cinv50_crc_atomic_check_head(struct nv50_head *head, 1158c2ecf20Sopenharmony_ci struct nv50_head_atom *asyh, 1168c2ecf20Sopenharmony_ci struct nv50_head_atom *armh) { return 0; } 1178c2ecf20Sopenharmony_cistatic inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {} 1188c2ecf20Sopenharmony_cistatic inline void 1198c2ecf20Sopenharmony_cinv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {} 1208c2ecf20Sopenharmony_cistatic inline void 1218c2ecf20Sopenharmony_cinv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {} 1228c2ecf20Sopenharmony_cistatic inline void 1238c2ecf20Sopenharmony_cinv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {} 1248c2ecf20Sopenharmony_cistatic inline void 1258c2ecf20Sopenharmony_cinv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {} 1268c2ecf20Sopenharmony_cistatic inline void 1278c2ecf20Sopenharmony_cinv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {} 1288c2ecf20Sopenharmony_cistatic inline void 1298c2ecf20Sopenharmony_cinv50_crc_atomic_clr(struct nv50_head *head) {} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ 1328c2ecf20Sopenharmony_ci#endif /* !__NV50_CRC_H__ */ 133