162306a36Sopenharmony_ci/* SPDX-License-Identifier: MIT */ 262306a36Sopenharmony_ci#ifndef __NV50_CRC_H__ 362306a36Sopenharmony_ci#define __NV50_CRC_H__ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/mutex.h> 662306a36Sopenharmony_ci#include <drm/drm_crtc.h> 762306a36Sopenharmony_ci#include <drm/drm_vblank_work.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <nvif/mem.h> 1062306a36Sopenharmony_ci#include <nvkm/subdev/bios.h> 1162306a36Sopenharmony_ci#include "nouveau_encoder.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistruct nv50_atom; 1462306a36Sopenharmony_cistruct nv50_disp; 1562306a36Sopenharmony_cistruct nv50_head; 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DEBUG_FS) 1862306a36Sopenharmony_cienum nv50_crc_source { 1962306a36Sopenharmony_ci NV50_CRC_SOURCE_NONE = 0, 2062306a36Sopenharmony_ci NV50_CRC_SOURCE_AUTO, 2162306a36Sopenharmony_ci NV50_CRC_SOURCE_RG, 2262306a36Sopenharmony_ci NV50_CRC_SOURCE_OUTP_ACTIVE, 2362306a36Sopenharmony_ci NV50_CRC_SOURCE_OUTP_COMPLETE, 2462306a36Sopenharmony_ci NV50_CRC_SOURCE_OUTP_INACTIVE, 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* RG -> SF (DP only) 2862306a36Sopenharmony_ci * -> SOR 2962306a36Sopenharmony_ci * -> PIOR 3062306a36Sopenharmony_ci * -> DAC 3162306a36Sopenharmony_ci */ 3262306a36Sopenharmony_cienum nv50_crc_source_type { 3362306a36Sopenharmony_ci NV50_CRC_SOURCE_TYPE_NONE = 0, 3462306a36Sopenharmony_ci NV50_CRC_SOURCE_TYPE_SOR, 3562306a36Sopenharmony_ci NV50_CRC_SOURCE_TYPE_PIOR, 3662306a36Sopenharmony_ci NV50_CRC_SOURCE_TYPE_DAC, 3762306a36Sopenharmony_ci NV50_CRC_SOURCE_TYPE_RG, 3862306a36Sopenharmony_ci NV50_CRC_SOURCE_TYPE_SF, 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistruct nv50_crc_notifier_ctx { 4262306a36Sopenharmony_ci struct nvif_mem mem; 4362306a36Sopenharmony_ci struct nvif_object ntfy; 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct nv50_crc_atom { 4762306a36Sopenharmony_ci enum nv50_crc_source src; 4862306a36Sopenharmony_ci}; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistruct nv50_crc_func { 5162306a36Sopenharmony_ci int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type type, 5262306a36Sopenharmony_ci struct nv50_crc_notifier_ctx *ctx); 5362306a36Sopenharmony_ci int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *); 5462306a36Sopenharmony_ci u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *, 5562306a36Sopenharmony_ci enum nv50_crc_source, int idx); 5662306a36Sopenharmony_ci bool (*ctx_finished)(struct nv50_head *, 5762306a36Sopenharmony_ci struct nv50_crc_notifier_ctx *); 5862306a36Sopenharmony_ci short flip_threshold; 5962306a36Sopenharmony_ci short num_entries; 6062306a36Sopenharmony_ci size_t notifier_len; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct nv50_crc { 6462306a36Sopenharmony_ci spinlock_t lock; 6562306a36Sopenharmony_ci struct nv50_crc_notifier_ctx ctx[2]; 6662306a36Sopenharmony_ci struct drm_vblank_work flip_work; 6762306a36Sopenharmony_ci enum nv50_crc_source src; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci u64 frame; 7062306a36Sopenharmony_ci short entry_idx; 7162306a36Sopenharmony_ci short flip_threshold; 7262306a36Sopenharmony_ci u8 ctx_idx : 1; 7362306a36Sopenharmony_ci bool ctx_changed : 1; 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_civoid nv50_crc_init(struct drm_device *dev); 7762306a36Sopenharmony_ciint nv50_head_crc_late_register(struct nv50_head *); 7862306a36Sopenharmony_civoid nv50_crc_handle_vblank(struct nv50_head *head); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ciint nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *); 8162306a36Sopenharmony_ciconst char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *); 8262306a36Sopenharmony_ciint nv50_crc_set_source(struct drm_crtc *, const char *); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ciint nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *, 8562306a36Sopenharmony_ci struct nv50_head_atom *); 8662306a36Sopenharmony_civoid nv50_crc_atomic_check_outp(struct nv50_atom *atom); 8762306a36Sopenharmony_civoid nv50_crc_atomic_stop_reporting(struct drm_atomic_state *); 8862306a36Sopenharmony_civoid nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *); 8962306a36Sopenharmony_civoid nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *); 9062306a36Sopenharmony_civoid nv50_crc_atomic_start_reporting(struct drm_atomic_state *); 9162306a36Sopenharmony_civoid nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *); 9262306a36Sopenharmony_civoid nv50_crc_atomic_clr(struct nv50_head *); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ciextern const struct nv50_crc_func crc907d; 9562306a36Sopenharmony_ciextern const struct nv50_crc_func crcc37d; 9662306a36Sopenharmony_ciextern const struct nv50_crc_func crcc57d; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#else /* IS_ENABLED(CONFIG_DEBUG_FS) */ 9962306a36Sopenharmony_cistruct nv50_crc {}; 10062306a36Sopenharmony_cistruct nv50_crc_func {}; 10162306a36Sopenharmony_cistruct nv50_crc_atom {}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#define nv50_crc_verify_source NULL 10462306a36Sopenharmony_ci#define nv50_crc_get_sources NULL 10562306a36Sopenharmony_ci#define nv50_crc_set_source NULL 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_cistatic inline void nv50_crc_init(struct drm_device *dev) {} 10862306a36Sopenharmony_cistatic inline int 10962306a36Sopenharmony_cinv50_head_crc_late_register(struct nv50_head *head) { return 0; } 11062306a36Sopenharmony_cistatic inline void nv50_crc_handle_vblank(struct nv50_head *head) {} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic inline int 11362306a36Sopenharmony_cinv50_crc_atomic_check_head(struct nv50_head *head, 11462306a36Sopenharmony_ci struct nv50_head_atom *asyh, 11562306a36Sopenharmony_ci struct nv50_head_atom *armh) { return 0; } 11662306a36Sopenharmony_cistatic inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {} 11762306a36Sopenharmony_cistatic inline void 11862306a36Sopenharmony_cinv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {} 11962306a36Sopenharmony_cistatic inline void 12062306a36Sopenharmony_cinv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {} 12162306a36Sopenharmony_cistatic inline void 12262306a36Sopenharmony_cinv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {} 12362306a36Sopenharmony_cistatic inline void 12462306a36Sopenharmony_cinv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {} 12562306a36Sopenharmony_cistatic inline void 12662306a36Sopenharmony_cinv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {} 12762306a36Sopenharmony_cistatic inline void 12862306a36Sopenharmony_cinv50_crc_atomic_clr(struct nv50_head *head) {} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ 13162306a36Sopenharmony_ci#endif /* !__NV50_CRC_H__ */ 132