18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _SUNXI_ENGINE_H_
78c2ecf20Sopenharmony_ci#define _SUNXI_ENGINE_H_
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistruct drm_plane;
108c2ecf20Sopenharmony_cistruct drm_device;
118c2ecf20Sopenharmony_cistruct drm_crtc_state;
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistruct sunxi_engine;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/**
168c2ecf20Sopenharmony_ci * struct sunxi_engine_ops - helper operations for sunXi engines
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci * These hooks are used by the common part of the DRM driver to
198c2ecf20Sopenharmony_ci * implement the proper behaviour.
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_cistruct sunxi_engine_ops {
228c2ecf20Sopenharmony_ci	/**
238c2ecf20Sopenharmony_ci	 * @atomic_begin:
248c2ecf20Sopenharmony_ci	 *
258c2ecf20Sopenharmony_ci	 * This callback allows to prepare our engine for an atomic
268c2ecf20Sopenharmony_ci	 * update. This is mirroring the
278c2ecf20Sopenharmony_ci	 * &drm_crtc_helper_funcs.atomic_begin callback, so any
288c2ecf20Sopenharmony_ci	 * documentation there applies.
298c2ecf20Sopenharmony_ci	 *
308c2ecf20Sopenharmony_ci	 * This function is optional.
318c2ecf20Sopenharmony_ci	 */
328c2ecf20Sopenharmony_ci	void (*atomic_begin)(struct sunxi_engine *engine,
338c2ecf20Sopenharmony_ci			     struct drm_crtc_state *old_state);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/**
368c2ecf20Sopenharmony_ci	 * @atomic_check:
378c2ecf20Sopenharmony_ci	 *
388c2ecf20Sopenharmony_ci	 * This callback allows to validate plane-update related CRTC
398c2ecf20Sopenharmony_ci	 * constraints specific to engines. This is mirroring the
408c2ecf20Sopenharmony_ci	 * &drm_crtc_helper_funcs.atomic_check callback, so any
418c2ecf20Sopenharmony_ci	 * documentation there applies.
428c2ecf20Sopenharmony_ci	 *
438c2ecf20Sopenharmony_ci	 * This function is optional.
448c2ecf20Sopenharmony_ci	 *
458c2ecf20Sopenharmony_ci	 * RETURNS:
468c2ecf20Sopenharmony_ci	 *
478c2ecf20Sopenharmony_ci	 * 0 on success or a negative error code.
488c2ecf20Sopenharmony_ci	 */
498c2ecf20Sopenharmony_ci	int (*atomic_check)(struct sunxi_engine *engine,
508c2ecf20Sopenharmony_ci			    struct drm_crtc_state *state);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	/**
538c2ecf20Sopenharmony_ci	 * @commit:
548c2ecf20Sopenharmony_ci	 *
558c2ecf20Sopenharmony_ci	 * This callback will trigger the hardware switch to commit
568c2ecf20Sopenharmony_ci	 * the new configuration that has been setup during the next
578c2ecf20Sopenharmony_ci	 * vblank period.
588c2ecf20Sopenharmony_ci	 *
598c2ecf20Sopenharmony_ci	 * This function is optional.
608c2ecf20Sopenharmony_ci	 */
618c2ecf20Sopenharmony_ci	void (*commit)(struct sunxi_engine *engine);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/**
648c2ecf20Sopenharmony_ci	 * @layers_init:
658c2ecf20Sopenharmony_ci	 *
668c2ecf20Sopenharmony_ci	 * This callback is used to allocate, initialize and register
678c2ecf20Sopenharmony_ci	 * the layers supported by that engine.
688c2ecf20Sopenharmony_ci	 *
698c2ecf20Sopenharmony_ci	 * This function is mandatory.
708c2ecf20Sopenharmony_ci	 *
718c2ecf20Sopenharmony_ci	 * RETURNS:
728c2ecf20Sopenharmony_ci	 *
738c2ecf20Sopenharmony_ci	 * The array of struct drm_plane backing the layers, or an
748c2ecf20Sopenharmony_ci	 * error pointer on failure.
758c2ecf20Sopenharmony_ci	 */
768c2ecf20Sopenharmony_ci	struct drm_plane **(*layers_init)(struct drm_device *drm,
778c2ecf20Sopenharmony_ci					  struct sunxi_engine *engine);
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	/**
808c2ecf20Sopenharmony_ci	 * @apply_color_correction:
818c2ecf20Sopenharmony_ci	 *
828c2ecf20Sopenharmony_ci	 * This callback will enable the color correction in the
838c2ecf20Sopenharmony_ci	 * engine. This is useful only for the composite output.
848c2ecf20Sopenharmony_ci	 *
858c2ecf20Sopenharmony_ci	 * This function is optional.
868c2ecf20Sopenharmony_ci	 */
878c2ecf20Sopenharmony_ci	void (*apply_color_correction)(struct sunxi_engine *engine);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	/**
908c2ecf20Sopenharmony_ci	 * @disable_color_correction:
918c2ecf20Sopenharmony_ci	 *
928c2ecf20Sopenharmony_ci	 * This callback will stop the color correction in the
938c2ecf20Sopenharmony_ci	 * engine. This is useful only for the composite output.
948c2ecf20Sopenharmony_ci	 *
958c2ecf20Sopenharmony_ci	 * This function is optional.
968c2ecf20Sopenharmony_ci	 */
978c2ecf20Sopenharmony_ci	void (*disable_color_correction)(struct sunxi_engine *engine);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	/**
1008c2ecf20Sopenharmony_ci	 * @vblank_quirk:
1018c2ecf20Sopenharmony_ci	 *
1028c2ecf20Sopenharmony_ci	 * This callback is used to implement engine-specific
1038c2ecf20Sopenharmony_ci	 * behaviour part of the VBLANK event. It is run with all the
1048c2ecf20Sopenharmony_ci	 * constraints of an interrupt (can't sleep, all local
1058c2ecf20Sopenharmony_ci	 * interrupts disabled) and therefore should be as fast as
1068c2ecf20Sopenharmony_ci	 * possible.
1078c2ecf20Sopenharmony_ci	 *
1088c2ecf20Sopenharmony_ci	 * This function is optional.
1098c2ecf20Sopenharmony_ci	 */
1108c2ecf20Sopenharmony_ci	void (*vblank_quirk)(struct sunxi_engine *engine);
1118c2ecf20Sopenharmony_ci};
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci/**
1148c2ecf20Sopenharmony_ci * struct sunxi_engine - the common parts of an engine for sun4i-drm driver
1158c2ecf20Sopenharmony_ci * @ops:	the operations of the engine
1168c2ecf20Sopenharmony_ci * @node:	the of device node of the engine
1178c2ecf20Sopenharmony_ci * @regs:	the regmap of the engine
1188c2ecf20Sopenharmony_ci * @id:		the id of the engine (-1 if not used)
1198c2ecf20Sopenharmony_ci */
1208c2ecf20Sopenharmony_cistruct sunxi_engine {
1218c2ecf20Sopenharmony_ci	const struct sunxi_engine_ops	*ops;
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	struct device_node		*node;
1248c2ecf20Sopenharmony_ci	struct regmap			*regs;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	int id;
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	/* Engine list management */
1298c2ecf20Sopenharmony_ci	struct list_head		list;
1308c2ecf20Sopenharmony_ci};
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci/**
1338c2ecf20Sopenharmony_ci * sunxi_engine_commit() - commit all changes of the engine
1348c2ecf20Sopenharmony_ci * @engine:	pointer to the engine
1358c2ecf20Sopenharmony_ci */
1368c2ecf20Sopenharmony_cistatic inline void
1378c2ecf20Sopenharmony_cisunxi_engine_commit(struct sunxi_engine *engine)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	if (engine->ops && engine->ops->commit)
1408c2ecf20Sopenharmony_ci		engine->ops->commit(engine);
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci/**
1448c2ecf20Sopenharmony_ci * sunxi_engine_layers_init() - Create planes (layers) for the engine
1458c2ecf20Sopenharmony_ci * @drm:	pointer to the drm_device for which planes will be created
1468c2ecf20Sopenharmony_ci * @engine:	pointer to the engine
1478c2ecf20Sopenharmony_ci */
1488c2ecf20Sopenharmony_cistatic inline struct drm_plane **
1498c2ecf20Sopenharmony_cisunxi_engine_layers_init(struct drm_device *drm, struct sunxi_engine *engine)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	if (engine->ops && engine->ops->layers_init)
1528c2ecf20Sopenharmony_ci		return engine->ops->layers_init(drm, engine);
1538c2ecf20Sopenharmony_ci	return ERR_PTR(-ENOSYS);
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/**
1578c2ecf20Sopenharmony_ci * sunxi_engine_apply_color_correction - Apply the RGB2YUV color correction
1588c2ecf20Sopenharmony_ci * @engine:	pointer to the engine
1598c2ecf20Sopenharmony_ci *
1608c2ecf20Sopenharmony_ci * This functionality is optional for an engine, however, if the engine is
1618c2ecf20Sopenharmony_ci * intended to be used with TV Encoder, the output will be incorrect
1628c2ecf20Sopenharmony_ci * without the color correction, due to TV Encoder expects the engine to
1638c2ecf20Sopenharmony_ci * output directly YUV signal.
1648c2ecf20Sopenharmony_ci */
1658c2ecf20Sopenharmony_cistatic inline void
1668c2ecf20Sopenharmony_cisunxi_engine_apply_color_correction(struct sunxi_engine *engine)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	if (engine->ops && engine->ops->apply_color_correction)
1698c2ecf20Sopenharmony_ci		engine->ops->apply_color_correction(engine);
1708c2ecf20Sopenharmony_ci}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci/**
1738c2ecf20Sopenharmony_ci * sunxi_engine_disable_color_correction - Disable the color space correction
1748c2ecf20Sopenharmony_ci * @engine:	pointer to the engine
1758c2ecf20Sopenharmony_ci *
1768c2ecf20Sopenharmony_ci * This function is paired with apply_color_correction().
1778c2ecf20Sopenharmony_ci */
1788c2ecf20Sopenharmony_cistatic inline void
1798c2ecf20Sopenharmony_cisunxi_engine_disable_color_correction(struct sunxi_engine *engine)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	if (engine->ops && engine->ops->disable_color_correction)
1828c2ecf20Sopenharmony_ci		engine->ops->disable_color_correction(engine);
1838c2ecf20Sopenharmony_ci}
1848c2ecf20Sopenharmony_ci#endif /* _SUNXI_ENGINE_H_ */
185