132 lines · c
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 13struct nv50_atom;14struct nv50_disp;15struct nv50_head;16 17#if IS_ENABLED(CONFIG_DEBUG_FS)18enum 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 * -> SOR29 * -> PIOR30 * -> DAC31 */32enum 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 41struct nv50_crc_notifier_ctx {42 struct nvif_mem mem;43 struct nvif_object ntfy;44};45 46struct nv50_crc_atom {47 enum nv50_crc_source src;48};49 50struct nv50_crc_func {51 int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type type,52 struct nv50_crc_notifier_ctx *ctx);53 int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);54 u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,55 enum nv50_crc_source, int idx);56 bool (*ctx_finished)(struct nv50_head *,57 struct nv50_crc_notifier_ctx *);58 short flip_threshold;59 short num_entries;60 size_t notifier_len;61};62 63struct nv50_crc {64 spinlock_t lock;65 struct nv50_crc_notifier_ctx ctx[2];66 struct drm_vblank_work flip_work;67 enum nv50_crc_source src;68 69 u64 frame;70 short entry_idx;71 short flip_threshold;72 u8 ctx_idx : 1;73 bool ctx_changed : 1;74};75 76void nv50_crc_init(struct drm_device *dev);77int nv50_head_crc_late_register(struct nv50_head *);78void nv50_crc_handle_vblank(struct nv50_head *head);79 80int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *);81const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *);82int nv50_crc_set_source(struct drm_crtc *, const char *);83 84int nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,85 struct nv50_head_atom *);86void nv50_crc_atomic_check_outp(struct nv50_atom *atom);87void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *);88void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *);89void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *);90void nv50_crc_atomic_start_reporting(struct drm_atomic_state *);91void nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *);92void nv50_crc_atomic_clr(struct nv50_head *);93 94extern const struct nv50_crc_func crc907d;95extern const struct nv50_crc_func crcc37d;96extern const struct nv50_crc_func crcc57d;97 98#else /* IS_ENABLED(CONFIG_DEBUG_FS) */99struct nv50_crc {};100struct nv50_crc_func {};101struct nv50_crc_atom {};102 103#define nv50_crc_verify_source NULL104#define nv50_crc_get_sources NULL105#define nv50_crc_set_source NULL106 107static inline void nv50_crc_init(struct drm_device *dev) {}108static inline int109nv50_head_crc_late_register(struct nv50_head *head) { return 0; }110static inline void nv50_crc_handle_vblank(struct nv50_head *head) {}111 112static inline int113nv50_crc_atomic_check_head(struct nv50_head *head,114 struct nv50_head_atom *asyh,115 struct nv50_head_atom *armh) { return 0; }116static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {}117static inline void118nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {}119static inline void120nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {}121static inline void122nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {}123static inline void124nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {}125static inline void126nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {}127static inline void128nv50_crc_atomic_clr(struct nv50_head *head) {}129 130#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */131#endif /* !__NV50_CRC_H__ */132