162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _SUNXI_ENGINE_H_ 762306a36Sopenharmony_ci#define _SUNXI_ENGINE_H_ 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistruct drm_plane; 1062306a36Sopenharmony_cistruct drm_device; 1162306a36Sopenharmony_cistruct drm_crtc_state; 1262306a36Sopenharmony_cistruct drm_display_mode; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct sunxi_engine; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/** 1762306a36Sopenharmony_ci * struct sunxi_engine_ops - helper operations for sunXi engines 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * These hooks are used by the common part of the DRM driver to 2062306a36Sopenharmony_ci * implement the proper behaviour. 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_cistruct sunxi_engine_ops { 2362306a36Sopenharmony_ci /** 2462306a36Sopenharmony_ci * @atomic_begin: 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * This callback allows to prepare our engine for an atomic 2762306a36Sopenharmony_ci * update. This is mirroring the 2862306a36Sopenharmony_ci * &drm_crtc_helper_funcs.atomic_begin callback, so any 2962306a36Sopenharmony_ci * documentation there applies. 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * This function is optional. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci void (*atomic_begin)(struct sunxi_engine *engine, 3462306a36Sopenharmony_ci struct drm_crtc_state *old_state); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci /** 3762306a36Sopenharmony_ci * @atomic_check: 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * This callback allows to validate plane-update related CRTC 4062306a36Sopenharmony_ci * constraints specific to engines. This is mirroring the 4162306a36Sopenharmony_ci * &drm_crtc_helper_funcs.atomic_check callback, so any 4262306a36Sopenharmony_ci * documentation there applies. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * This function is optional. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * RETURNS: 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * 0 on success or a negative error code. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci int (*atomic_check)(struct sunxi_engine *engine, 5162306a36Sopenharmony_ci struct drm_crtc_state *state); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /** 5462306a36Sopenharmony_ci * @commit: 5562306a36Sopenharmony_ci * 5662306a36Sopenharmony_ci * This callback will trigger the hardware switch to commit 5762306a36Sopenharmony_ci * the new configuration that has been setup during the next 5862306a36Sopenharmony_ci * vblank period. 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * This function is optional. 6162306a36Sopenharmony_ci */ 6262306a36Sopenharmony_ci void (*commit)(struct sunxi_engine *engine); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci /** 6562306a36Sopenharmony_ci * @layers_init: 6662306a36Sopenharmony_ci * 6762306a36Sopenharmony_ci * This callback is used to allocate, initialize and register 6862306a36Sopenharmony_ci * the layers supported by that engine. 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * This function is mandatory. 7162306a36Sopenharmony_ci * 7262306a36Sopenharmony_ci * RETURNS: 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * The array of struct drm_plane backing the layers, or an 7562306a36Sopenharmony_ci * error pointer on failure. 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci struct drm_plane **(*layers_init)(struct drm_device *drm, 7862306a36Sopenharmony_ci struct sunxi_engine *engine); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci /** 8162306a36Sopenharmony_ci * @apply_color_correction: 8262306a36Sopenharmony_ci * 8362306a36Sopenharmony_ci * This callback will enable the color correction in the 8462306a36Sopenharmony_ci * engine. This is useful only for the composite output. 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * This function is optional. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci void (*apply_color_correction)(struct sunxi_engine *engine); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /** 9162306a36Sopenharmony_ci * @disable_color_correction: 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * This callback will stop the color correction in the 9462306a36Sopenharmony_ci * engine. This is useful only for the composite output. 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * This function is optional. 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ci void (*disable_color_correction)(struct sunxi_engine *engine); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /** 10162306a36Sopenharmony_ci * @vblank_quirk: 10262306a36Sopenharmony_ci * 10362306a36Sopenharmony_ci * This callback is used to implement engine-specific 10462306a36Sopenharmony_ci * behaviour part of the VBLANK event. It is run with all the 10562306a36Sopenharmony_ci * constraints of an interrupt (can't sleep, all local 10662306a36Sopenharmony_ci * interrupts disabled) and therefore should be as fast as 10762306a36Sopenharmony_ci * possible. 10862306a36Sopenharmony_ci * 10962306a36Sopenharmony_ci * This function is optional. 11062306a36Sopenharmony_ci */ 11162306a36Sopenharmony_ci void (*vblank_quirk)(struct sunxi_engine *engine); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci /** 11462306a36Sopenharmony_ci * @mode_set 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * This callback is used to set mode related parameters 11762306a36Sopenharmony_ci * like interlacing, screen size, etc. once per mode set. 11862306a36Sopenharmony_ci * 11962306a36Sopenharmony_ci * This function is optional. 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ci void (*mode_set)(struct sunxi_engine *engine, 12262306a36Sopenharmony_ci const struct drm_display_mode *mode); 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/** 12662306a36Sopenharmony_ci * struct sunxi_engine - the common parts of an engine for sun4i-drm driver 12762306a36Sopenharmony_ci * @ops: the operations of the engine 12862306a36Sopenharmony_ci * @node: the of device node of the engine 12962306a36Sopenharmony_ci * @regs: the regmap of the engine 13062306a36Sopenharmony_ci * @id: the id of the engine (-1 if not used) 13162306a36Sopenharmony_ci */ 13262306a36Sopenharmony_cistruct sunxi_engine { 13362306a36Sopenharmony_ci const struct sunxi_engine_ops *ops; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci struct device_node *node; 13662306a36Sopenharmony_ci struct regmap *regs; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci int id; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci /* Engine list management */ 14162306a36Sopenharmony_ci struct list_head list; 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/** 14562306a36Sopenharmony_ci * sunxi_engine_commit() - commit all changes of the engine 14662306a36Sopenharmony_ci * @engine: pointer to the engine 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_cistatic inline void 14962306a36Sopenharmony_cisunxi_engine_commit(struct sunxi_engine *engine) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci if (engine->ops && engine->ops->commit) 15262306a36Sopenharmony_ci engine->ops->commit(engine); 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci/** 15662306a36Sopenharmony_ci * sunxi_engine_layers_init() - Create planes (layers) for the engine 15762306a36Sopenharmony_ci * @drm: pointer to the drm_device for which planes will be created 15862306a36Sopenharmony_ci * @engine: pointer to the engine 15962306a36Sopenharmony_ci */ 16062306a36Sopenharmony_cistatic inline struct drm_plane ** 16162306a36Sopenharmony_cisunxi_engine_layers_init(struct drm_device *drm, struct sunxi_engine *engine) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci if (engine->ops && engine->ops->layers_init) 16462306a36Sopenharmony_ci return engine->ops->layers_init(drm, engine); 16562306a36Sopenharmony_ci return ERR_PTR(-ENOSYS); 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/** 16962306a36Sopenharmony_ci * sunxi_engine_apply_color_correction - Apply the RGB2YUV color correction 17062306a36Sopenharmony_ci * @engine: pointer to the engine 17162306a36Sopenharmony_ci * 17262306a36Sopenharmony_ci * This functionality is optional for an engine, however, if the engine is 17362306a36Sopenharmony_ci * intended to be used with TV Encoder, the output will be incorrect 17462306a36Sopenharmony_ci * without the color correction, due to TV Encoder expects the engine to 17562306a36Sopenharmony_ci * output directly YUV signal. 17662306a36Sopenharmony_ci */ 17762306a36Sopenharmony_cistatic inline void 17862306a36Sopenharmony_cisunxi_engine_apply_color_correction(struct sunxi_engine *engine) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci if (engine->ops && engine->ops->apply_color_correction) 18162306a36Sopenharmony_ci engine->ops->apply_color_correction(engine); 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci/** 18562306a36Sopenharmony_ci * sunxi_engine_disable_color_correction - Disable the color space correction 18662306a36Sopenharmony_ci * @engine: pointer to the engine 18762306a36Sopenharmony_ci * 18862306a36Sopenharmony_ci * This function is paired with apply_color_correction(). 18962306a36Sopenharmony_ci */ 19062306a36Sopenharmony_cistatic inline void 19162306a36Sopenharmony_cisunxi_engine_disable_color_correction(struct sunxi_engine *engine) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci if (engine->ops && engine->ops->disable_color_correction) 19462306a36Sopenharmony_ci engine->ops->disable_color_correction(engine); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/** 19862306a36Sopenharmony_ci * sunxi_engine_mode_set - Inform engine of a new mode 19962306a36Sopenharmony_ci * @engine: pointer to the engine 20062306a36Sopenharmony_ci * @mode: new mode 20162306a36Sopenharmony_ci * 20262306a36Sopenharmony_ci * Engine can use this functionality to set specifics once per mode change. 20362306a36Sopenharmony_ci */ 20462306a36Sopenharmony_cistatic inline void 20562306a36Sopenharmony_cisunxi_engine_mode_set(struct sunxi_engine *engine, 20662306a36Sopenharmony_ci const struct drm_display_mode *mode) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci if (engine->ops && engine->ops->mode_set) 20962306a36Sopenharmony_ci engine->ops->mode_set(engine, mode); 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci#endif /* _SUNXI_ENGINE_H_ */ 212