1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
2 | /* |
3 | * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> |
4 | */ |
5 | |
6 | #ifndef _SUNXI_ENGINE_H_ |
7 | #define _SUNXI_ENGINE_H_ |
8 | |
9 | struct drm_plane; |
10 | struct drm_device; |
11 | struct drm_crtc_state; |
12 | struct drm_display_mode; |
13 | |
14 | struct sunxi_engine; |
15 | |
16 | /** |
17 | * struct sunxi_engine_ops - helper operations for sunXi engines |
18 | * |
19 | * These hooks are used by the common part of the DRM driver to |
20 | * implement the proper behaviour. |
21 | */ |
22 | struct sunxi_engine_ops { |
23 | /** |
24 | * @atomic_begin: |
25 | * |
26 | * This callback allows to prepare our engine for an atomic |
27 | * update. This is mirroring the |
28 | * &drm_crtc_helper_funcs.atomic_begin callback, so any |
29 | * documentation there applies. |
30 | * |
31 | * This function is optional. |
32 | */ |
33 | void (*atomic_begin)(struct sunxi_engine *engine, |
34 | struct drm_crtc_state *old_state); |
35 | |
36 | /** |
37 | * @atomic_check: |
38 | * |
39 | * This callback allows to validate plane-update related CRTC |
40 | * constraints specific to engines. This is mirroring the |
41 | * &drm_crtc_helper_funcs.atomic_check callback, so any |
42 | * documentation there applies. |
43 | * |
44 | * This function is optional. |
45 | * |
46 | * RETURNS: |
47 | * |
48 | * 0 on success or a negative error code. |
49 | */ |
50 | int (*atomic_check)(struct sunxi_engine *engine, |
51 | struct drm_crtc_state *state); |
52 | |
53 | /** |
54 | * @commit: |
55 | * |
56 | * This callback will trigger the hardware switch to commit |
57 | * the new configuration that has been setup during the next |
58 | * vblank period. |
59 | * |
60 | * This function is optional. |
61 | */ |
62 | void (*commit)(struct sunxi_engine *engine); |
63 | |
64 | /** |
65 | * @layers_init: |
66 | * |
67 | * This callback is used to allocate, initialize and register |
68 | * the layers supported by that engine. |
69 | * |
70 | * This function is mandatory. |
71 | * |
72 | * RETURNS: |
73 | * |
74 | * The array of struct drm_plane backing the layers, or an |
75 | * error pointer on failure. |
76 | */ |
77 | struct drm_plane **(*layers_init)(struct drm_device *drm, |
78 | struct sunxi_engine *engine); |
79 | |
80 | /** |
81 | * @apply_color_correction: |
82 | * |
83 | * This callback will enable the color correction in the |
84 | * engine. This is useful only for the composite output. |
85 | * |
86 | * This function is optional. |
87 | */ |
88 | void (*apply_color_correction)(struct sunxi_engine *engine); |
89 | |
90 | /** |
91 | * @disable_color_correction: |
92 | * |
93 | * This callback will stop the color correction in the |
94 | * engine. This is useful only for the composite output. |
95 | * |
96 | * This function is optional. |
97 | */ |
98 | void (*disable_color_correction)(struct sunxi_engine *engine); |
99 | |
100 | /** |
101 | * @vblank_quirk: |
102 | * |
103 | * This callback is used to implement engine-specific |
104 | * behaviour part of the VBLANK event. It is run with all the |
105 | * constraints of an interrupt (can't sleep, all local |
106 | * interrupts disabled) and therefore should be as fast as |
107 | * possible. |
108 | * |
109 | * This function is optional. |
110 | */ |
111 | void (*vblank_quirk)(struct sunxi_engine *engine); |
112 | |
113 | /** |
114 | * @mode_set |
115 | * |
116 | * This callback is used to set mode related parameters |
117 | * like interlacing, screen size, etc. once per mode set. |
118 | * |
119 | * This function is optional. |
120 | */ |
121 | void (*mode_set)(struct sunxi_engine *engine, |
122 | const struct drm_display_mode *mode); |
123 | }; |
124 | |
125 | /** |
126 | * struct sunxi_engine - the common parts of an engine for sun4i-drm driver |
127 | * @ops: the operations of the engine |
128 | * @node: the of device node of the engine |
129 | * @regs: the regmap of the engine |
130 | * @id: the id of the engine (-1 if not used) |
131 | */ |
132 | struct sunxi_engine { |
133 | const struct sunxi_engine_ops *ops; |
134 | |
135 | struct device_node *node; |
136 | struct regmap *regs; |
137 | |
138 | int id; |
139 | |
140 | /* Engine list management */ |
141 | struct list_head list; |
142 | }; |
143 | |
144 | /** |
145 | * sunxi_engine_commit() - commit all changes of the engine |
146 | * @engine: pointer to the engine |
147 | */ |
148 | static inline void |
149 | sunxi_engine_commit(struct sunxi_engine *engine) |
150 | { |
151 | if (engine->ops && engine->ops->commit) |
152 | engine->ops->commit(engine); |
153 | } |
154 | |
155 | /** |
156 | * sunxi_engine_layers_init() - Create planes (layers) for the engine |
157 | * @drm: pointer to the drm_device for which planes will be created |
158 | * @engine: pointer to the engine |
159 | */ |
160 | static inline struct drm_plane ** |
161 | sunxi_engine_layers_init(struct drm_device *drm, struct sunxi_engine *engine) |
162 | { |
163 | if (engine->ops && engine->ops->layers_init) |
164 | return engine->ops->layers_init(drm, engine); |
165 | return ERR_PTR(error: -ENOSYS); |
166 | } |
167 | |
168 | /** |
169 | * sunxi_engine_apply_color_correction - Apply the RGB2YUV color correction |
170 | * @engine: pointer to the engine |
171 | * |
172 | * This functionality is optional for an engine, however, if the engine is |
173 | * intended to be used with TV Encoder, the output will be incorrect |
174 | * without the color correction, due to TV Encoder expects the engine to |
175 | * output directly YUV signal. |
176 | */ |
177 | static inline void |
178 | sunxi_engine_apply_color_correction(struct sunxi_engine *engine) |
179 | { |
180 | if (engine->ops && engine->ops->apply_color_correction) |
181 | engine->ops->apply_color_correction(engine); |
182 | } |
183 | |
184 | /** |
185 | * sunxi_engine_disable_color_correction - Disable the color space correction |
186 | * @engine: pointer to the engine |
187 | * |
188 | * This function is paired with apply_color_correction(). |
189 | */ |
190 | static inline void |
191 | sunxi_engine_disable_color_correction(struct sunxi_engine *engine) |
192 | { |
193 | if (engine->ops && engine->ops->disable_color_correction) |
194 | engine->ops->disable_color_correction(engine); |
195 | } |
196 | |
197 | /** |
198 | * sunxi_engine_mode_set - Inform engine of a new mode |
199 | * @engine: pointer to the engine |
200 | * @mode: new mode |
201 | * |
202 | * Engine can use this functionality to set specifics once per mode change. |
203 | */ |
204 | static inline void |
205 | sunxi_engine_mode_set(struct sunxi_engine *engine, |
206 | const struct drm_display_mode *mode) |
207 | { |
208 | if (engine->ops && engine->ops->mode_set) |
209 | engine->ops->mode_set(engine, mode); |
210 | } |
211 | #endif /* _SUNXI_ENGINE_H_ */ |
212 | |