summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sun4i/sunxi_engine.h
blob: ec8cf9b2bda41cbcdc23caefd2285d5fc9507334 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
 */

#ifndef _SUNXI_ENGINE_H_
#define _SUNXI_ENGINE_H_

struct drm_plane;
struct drm_device;
struct drm_crtc_state;
struct drm_display_mode;

struct sunxi_engine;

/**
 * struct sunxi_engine_ops - helper operations for sunXi engines
 *
 * These hooks are used by the common part of the DRM driver to
 * implement the proper behaviour.
 */
struct sunxi_engine_ops {
	/**
	 * @atomic_begin:
	 *
	 * This callback allows to prepare our engine for an atomic
	 * update. This is mirroring the
	 * &drm_crtc_helper_funcs.atomic_begin callback, so any
	 * documentation there applies.
	 *
	 * This function is optional.
	 */
	void (*atomic_begin)(struct sunxi_engine *engine,
			     struct drm_crtc_state *old_state);

	/**
	 * @atomic_check:
	 *
	 * This callback allows to validate plane-update related CRTC
	 * constraints specific to engines. This is mirroring the
	 * &drm_crtc_helper_funcs.atomic_check callback, so any
	 * documentation there applies.
	 *
	 * This function is optional.
	 *
	 * RETURNS:
	 *
	 * 0 on success or a negative error code.
	 */
	int (*atomic_check)(struct sunxi_engine *engine,
			    struct drm_crtc_state *state);

	/**
	 * @commit:
	 *
	 * This callback will trigger the hardware switch to commit
	 * the new configuration that has been setup during the next
	 * vblank period.
	 *
	 * This function is optional.
	 */
	void (*commit)(struct sunxi_engine *engine);

	/**
	 * @layers_init:
	 *
	 * This callback is used to allocate, initialize and register
	 * the layers supported by that engine.
	 *
	 * This function is mandatory.
	 *
	 * RETURNS:
	 *
	 * The array of struct drm_plane backing the layers, or an
	 * error pointer on failure.
	 */
	struct drm_plane **(*layers_init)(struct drm_device *drm,
					  struct sunxi_engine *engine);

	/**
	 * @apply_color_correction:
	 *
	 * This callback will enable the color correction in the
	 * engine. This is useful only for the composite output.
	 *
	 * This function is optional.
	 */
	void (*apply_color_correction)(struct sunxi_engine *engine);

	/**
	 * @disable_color_correction:
	 *
	 * This callback will stop the color correction in the
	 * engine. This is useful only for the composite output.
	 *
	 * This function is optional.
	 */
	void (*disable_color_correction)(struct sunxi_engine *engine);

	/**
	 * @vblank_quirk:
	 *
	 * This callback is used to implement engine-specific
	 * behaviour part of the VBLANK event. It is run with all the
	 * constraints of an interrupt (can't sleep, all local
	 * interrupts disabled) and therefore should be as fast as
	 * possible.
	 *
	 * This function is optional.
	 */
	void (*vblank_quirk)(struct sunxi_engine *engine);

	/**
	 * @mode_set
	 *
	 * This callback is used to set mode related parameters
	 * like interlacing, screen size, etc. once per mode set.
	 *
	 * This function is optional.
	 */
	void (*mode_set)(struct sunxi_engine *engine,
			 const struct drm_display_mode *mode);
};

/**
 * struct sunxi_engine - the common parts of an engine for sun4i-drm driver
 * @ops:	the operations of the engine
 * @node:	the of device node of the engine
 * @regs:	the regmap of the engine
 * @id:		the id of the engine (-1 if not used)
 */
struct sunxi_engine {
	const struct sunxi_engine_ops	*ops;

	struct device_node		*node;
	struct regmap			*regs;

	int id;

	/* Engine list management */
	struct list_head		list;
};

/**
 * sunxi_engine_commit() - commit all changes of the engine
 * @engine:	pointer to the engine
 */
static inline void
sunxi_engine_commit(struct sunxi_engine *engine)
{
	if (engine->ops && engine->ops->commit)
		engine->ops->commit(engine);
}

/**
 * sunxi_engine_layers_init() - Create planes (layers) for the engine
 * @drm:	pointer to the drm_device for which planes will be created
 * @engine:	pointer to the engine
 */
static inline struct drm_plane **
sunxi_engine_layers_init(struct drm_device *drm, struct sunxi_engine *engine)
{
	if (engine->ops && engine->ops->layers_init)
		return engine->ops->layers_init(drm, engine);
	return ERR_PTR(-ENOSYS);
}

/**
 * sunxi_engine_apply_color_correction - Apply the RGB2YUV color correction
 * @engine:	pointer to the engine
 *
 * This functionality is optional for an engine, however, if the engine is
 * intended to be used with TV Encoder, the output will be incorrect
 * without the color correction, due to TV Encoder expects the engine to
 * output directly YUV signal.
 */
static inline void
sunxi_engine_apply_color_correction(struct sunxi_engine *engine)
{
	if (engine->ops && engine->ops->apply_color_correction)
		engine->ops->apply_color_correction(engine);
}

/**
 * sunxi_engine_disable_color_correction - Disable the color space correction
 * @engine:	pointer to the engine
 *
 * This function is paired with apply_color_correction().
 */
static inline void
sunxi_engine_disable_color_correction(struct sunxi_engine *engine)
{
	if (engine->ops && engine->ops->disable_color_correction)
		engine->ops->disable_color_correction(engine);
}

/**
 * sunxi_engine_mode_set - Inform engine of a new mode
 * @engine:	pointer to the engine
 * @mode:	new mode
 *
 * Engine can use this functionality to set specifics once per mode change.
 */
static inline void
sunxi_engine_mode_set(struct sunxi_engine *engine,
		      const struct drm_display_mode *mode)
{
	if (engine->ops && engine->ops->mode_set)
		engine->ops->mode_set(engine, mode);
}
#endif /* _SUNXI_ENGINE_H_ */