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