132 lines
3.8 KiB
C
132 lines
3.8 KiB
C
|
/* SPDX-License-Identifier: MIT */
|
||
|
#ifndef __NV50_CRC_H__
|
||
|
#define __NV50_CRC_H__
|
||
|
|
||
|
#include <linux/mutex.h>
|
||
|
#include <drm/drm_crtc.h>
|
||
|
#include <drm/drm_vblank_work.h>
|
||
|
|
||
|
#include <nvif/mem.h>
|
||
|
#include <nvkm/subdev/bios.h>
|
||
|
#include "nouveau_encoder.h"
|
||
|
|
||
|
struct nv50_atom;
|
||
|
struct nv50_disp;
|
||
|
struct nv50_head;
|
||
|
|
||
|
#if IS_ENABLED(CONFIG_DEBUG_FS)
|
||
|
enum nv50_crc_source {
|
||
|
NV50_CRC_SOURCE_NONE = 0,
|
||
|
NV50_CRC_SOURCE_AUTO,
|
||
|
NV50_CRC_SOURCE_RG,
|
||
|
NV50_CRC_SOURCE_OUTP_ACTIVE,
|
||
|
NV50_CRC_SOURCE_OUTP_COMPLETE,
|
||
|
NV50_CRC_SOURCE_OUTP_INACTIVE,
|
||
|
};
|
||
|
|
||
|
/* RG -> SF (DP only)
|
||
|
* -> SOR
|
||
|
* -> PIOR
|
||
|
* -> DAC
|
||
|
*/
|
||
|
enum nv50_crc_source_type {
|
||
|
NV50_CRC_SOURCE_TYPE_NONE = 0,
|
||
|
NV50_CRC_SOURCE_TYPE_SOR,
|
||
|
NV50_CRC_SOURCE_TYPE_PIOR,
|
||
|
NV50_CRC_SOURCE_TYPE_DAC,
|
||
|
NV50_CRC_SOURCE_TYPE_RG,
|
||
|
NV50_CRC_SOURCE_TYPE_SF,
|
||
|
};
|
||
|
|
||
|
struct nv50_crc_notifier_ctx {
|
||
|
struct nvif_mem mem;
|
||
|
struct nvif_object ntfy;
|
||
|
};
|
||
|
|
||
|
struct nv50_crc_atom {
|
||
|
enum nv50_crc_source src;
|
||
|
};
|
||
|
|
||
|
struct nv50_crc_func {
|
||
|
int (*set_src)(struct nv50_head *, int or, enum nv50_crc_source_type type,
|
||
|
struct nv50_crc_notifier_ctx *ctx);
|
||
|
int (*set_ctx)(struct nv50_head *, struct nv50_crc_notifier_ctx *);
|
||
|
u32 (*get_entry)(struct nv50_head *, struct nv50_crc_notifier_ctx *,
|
||
|
enum nv50_crc_source, int idx);
|
||
|
bool (*ctx_finished)(struct nv50_head *,
|
||
|
struct nv50_crc_notifier_ctx *);
|
||
|
short flip_threshold;
|
||
|
short num_entries;
|
||
|
size_t notifier_len;
|
||
|
};
|
||
|
|
||
|
struct nv50_crc {
|
||
|
spinlock_t lock;
|
||
|
struct nv50_crc_notifier_ctx ctx[2];
|
||
|
struct drm_vblank_work flip_work;
|
||
|
enum nv50_crc_source src;
|
||
|
|
||
|
u64 frame;
|
||
|
short entry_idx;
|
||
|
short flip_threshold;
|
||
|
u8 ctx_idx : 1;
|
||
|
bool ctx_changed : 1;
|
||
|
};
|
||
|
|
||
|
void nv50_crc_init(struct drm_device *dev);
|
||
|
int nv50_head_crc_late_register(struct nv50_head *);
|
||
|
void nv50_crc_handle_vblank(struct nv50_head *head);
|
||
|
|
||
|
int nv50_crc_verify_source(struct drm_crtc *, const char *, size_t *);
|
||
|
const char *const *nv50_crc_get_sources(struct drm_crtc *, size_t *);
|
||
|
int nv50_crc_set_source(struct drm_crtc *, const char *);
|
||
|
|
||
|
int nv50_crc_atomic_check_head(struct nv50_head *, struct nv50_head_atom *,
|
||
|
struct nv50_head_atom *);
|
||
|
void nv50_crc_atomic_check_outp(struct nv50_atom *atom);
|
||
|
void nv50_crc_atomic_stop_reporting(struct drm_atomic_state *);
|
||
|
void nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *);
|
||
|
void nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *);
|
||
|
void nv50_crc_atomic_start_reporting(struct drm_atomic_state *);
|
||
|
void nv50_crc_atomic_set(struct nv50_head *, struct nv50_head_atom *);
|
||
|
void nv50_crc_atomic_clr(struct nv50_head *);
|
||
|
|
||
|
extern const struct nv50_crc_func crc907d;
|
||
|
extern const struct nv50_crc_func crcc37d;
|
||
|
extern const struct nv50_crc_func crcc57d;
|
||
|
|
||
|
#else /* IS_ENABLED(CONFIG_DEBUG_FS) */
|
||
|
struct nv50_crc {};
|
||
|
struct nv50_crc_func {};
|
||
|
struct nv50_crc_atom {};
|
||
|
|
||
|
#define nv50_crc_verify_source NULL
|
||
|
#define nv50_crc_get_sources NULL
|
||
|
#define nv50_crc_set_source NULL
|
||
|
|
||
|
static inline void nv50_crc_init(struct drm_device *dev) {}
|
||
|
static inline int
|
||
|
nv50_head_crc_late_register(struct nv50_head *head) { return 0; }
|
||
|
static inline void nv50_crc_handle_vblank(struct nv50_head *head) {}
|
||
|
|
||
|
static inline int
|
||
|
nv50_crc_atomic_check_head(struct nv50_head *head,
|
||
|
struct nv50_head_atom *asyh,
|
||
|
struct nv50_head_atom *armh) { return 0; }
|
||
|
static inline void nv50_crc_atomic_check_outp(struct nv50_atom *atom) {}
|
||
|
static inline void
|
||
|
nv50_crc_atomic_stop_reporting(struct drm_atomic_state *state) {}
|
||
|
static inline void
|
||
|
nv50_crc_atomic_init_notifier_contexts(struct drm_atomic_state *state) {}
|
||
|
static inline void
|
||
|
nv50_crc_atomic_release_notifier_contexts(struct drm_atomic_state *state) {}
|
||
|
static inline void
|
||
|
nv50_crc_atomic_start_reporting(struct drm_atomic_state *state) {}
|
||
|
static inline void
|
||
|
nv50_crc_atomic_set(struct nv50_head *head, struct nv50_head_atom *state) {}
|
||
|
static inline void
|
||
|
nv50_crc_atomic_clr(struct nv50_head *head) {}
|
||
|
|
||
|
#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
|
||
|
#endif /* !__NV50_CRC_H__ */
|