xref: /openbmc/linux/drivers/gpu/drm/exynos/exynos_drm_ipp.h (revision 976e3645923bdd2fe7893aae33fd7a21098bfb28)
1*2874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
29913f74fSMarek Szyprowski /*
39913f74fSMarek Szyprowski  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
49913f74fSMarek Szyprowski  */
59913f74fSMarek Szyprowski 
69913f74fSMarek Szyprowski #ifndef _EXYNOS_DRM_IPP_H_
79913f74fSMarek Szyprowski #define _EXYNOS_DRM_IPP_H_
89913f74fSMarek Szyprowski 
99913f74fSMarek Szyprowski struct exynos_drm_ipp;
109913f74fSMarek Szyprowski struct exynos_drm_ipp_task;
119913f74fSMarek Szyprowski 
129913f74fSMarek Szyprowski /**
139913f74fSMarek Szyprowski  * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions
149913f74fSMarek Szyprowski  */
159913f74fSMarek Szyprowski struct exynos_drm_ipp_funcs {
169913f74fSMarek Szyprowski 	/**
179913f74fSMarek Szyprowski 	 * @commit:
189913f74fSMarek Szyprowski 	 *
199913f74fSMarek Szyprowski 	 * This is the main entry point to start framebuffer processing
209913f74fSMarek Szyprowski 	 * in the hardware. The exynos_drm_ipp_task has been already validated.
219913f74fSMarek Szyprowski 	 * This function must not wait until the device finishes processing.
229913f74fSMarek Szyprowski 	 * When the driver finishes processing, it has to call
239913f74fSMarek Szyprowski 	 * exynos_exynos_drm_ipp_task_done() function.
249913f74fSMarek Szyprowski 	 *
259913f74fSMarek Szyprowski 	 * RETURNS:
269913f74fSMarek Szyprowski 	 *
279913f74fSMarek Szyprowski 	 * 0 on success or negative error codes in case of failure.
289913f74fSMarek Szyprowski 	 */
299913f74fSMarek Szyprowski 	int (*commit)(struct exynos_drm_ipp *ipp,
309913f74fSMarek Szyprowski 		      struct exynos_drm_ipp_task *task);
319913f74fSMarek Szyprowski 
329913f74fSMarek Szyprowski 	/**
339913f74fSMarek Szyprowski 	 * @abort:
349913f74fSMarek Szyprowski 	 *
359913f74fSMarek Szyprowski 	 * Informs the driver that it has to abort the currently running
369913f74fSMarek Szyprowski 	 * task as soon as possible (i.e. as soon as it can stop the device
379913f74fSMarek Szyprowski 	 * safely), even if the task would not have been finished by then.
389913f74fSMarek Szyprowski 	 * After the driver performs the necessary steps, it has to call
399913f74fSMarek Szyprowski 	 * exynos_drm_ipp_task_done() (as if the task ended normally).
409913f74fSMarek Szyprowski 	 * This function does not have to (and will usually not) wait
419913f74fSMarek Szyprowski 	 * until the device enters a state when it can be stopped.
429913f74fSMarek Szyprowski 	 */
439913f74fSMarek Szyprowski 	void (*abort)(struct exynos_drm_ipp *ipp,
449913f74fSMarek Szyprowski 		      struct exynos_drm_ipp_task *task);
459913f74fSMarek Szyprowski };
469913f74fSMarek Szyprowski 
479913f74fSMarek Szyprowski /**
489913f74fSMarek Szyprowski  * struct exynos_drm_ipp - central picture processor module structure
499913f74fSMarek Szyprowski  */
509913f74fSMarek Szyprowski struct exynos_drm_ipp {
518b955034SInki Dae 	struct drm_device *drm_dev;
528b955034SInki Dae 	struct device *dev;
539913f74fSMarek Szyprowski 	struct list_head head;
549913f74fSMarek Szyprowski 	unsigned int id;
559913f74fSMarek Szyprowski 
569913f74fSMarek Szyprowski 	const char *name;
579913f74fSMarek Szyprowski 	const struct exynos_drm_ipp_funcs *funcs;
589913f74fSMarek Szyprowski 	unsigned int capabilities;
599913f74fSMarek Szyprowski 	const struct exynos_drm_ipp_formats *formats;
609913f74fSMarek Szyprowski 	unsigned int num_formats;
619913f74fSMarek Szyprowski 	atomic_t sequence;
629913f74fSMarek Szyprowski 
639913f74fSMarek Szyprowski 	spinlock_t lock;
649913f74fSMarek Szyprowski 	struct exynos_drm_ipp_task *task;
659913f74fSMarek Szyprowski 	struct list_head todo_list;
669913f74fSMarek Szyprowski 	wait_queue_head_t done_wq;
679913f74fSMarek Szyprowski };
689913f74fSMarek Szyprowski 
699913f74fSMarek Szyprowski struct exynos_drm_ipp_buffer {
709913f74fSMarek Szyprowski 	struct drm_exynos_ipp_task_buffer buf;
719913f74fSMarek Szyprowski 	struct drm_exynos_ipp_task_rect rect;
729913f74fSMarek Szyprowski 
739913f74fSMarek Szyprowski 	struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
749913f74fSMarek Szyprowski 	const struct drm_format_info *format;
759913f74fSMarek Szyprowski 	dma_addr_t dma_addr[MAX_FB_BUFFER];
769913f74fSMarek Szyprowski };
779913f74fSMarek Szyprowski 
789913f74fSMarek Szyprowski /**
799913f74fSMarek Szyprowski  * struct exynos_drm_ipp_task - a structure describing transformation that
809913f74fSMarek Szyprowski  * has to be performed by the picture processor hardware module
819913f74fSMarek Szyprowski  */
829913f74fSMarek Szyprowski struct exynos_drm_ipp_task {
838b955034SInki Dae 	struct device *dev;
849913f74fSMarek Szyprowski 	struct exynos_drm_ipp *ipp;
859913f74fSMarek Szyprowski 	struct list_head head;
869913f74fSMarek Szyprowski 
879913f74fSMarek Szyprowski 	struct exynos_drm_ipp_buffer src;
889913f74fSMarek Szyprowski 	struct exynos_drm_ipp_buffer dst;
899913f74fSMarek Szyprowski 
909913f74fSMarek Szyprowski 	struct drm_exynos_ipp_task_transform transform;
919913f74fSMarek Szyprowski 	struct drm_exynos_ipp_task_alpha alpha;
929913f74fSMarek Szyprowski 
939913f74fSMarek Szyprowski 	struct work_struct cleanup_work;
949913f74fSMarek Szyprowski 	unsigned int flags;
959913f74fSMarek Szyprowski 	int ret;
969913f74fSMarek Szyprowski 
979913f74fSMarek Szyprowski 	struct drm_pending_exynos_ipp_event *event;
989913f74fSMarek Szyprowski };
999913f74fSMarek Szyprowski 
1009913f74fSMarek Szyprowski #define DRM_EXYNOS_IPP_TASK_DONE	(1 << 0)
1019913f74fSMarek Szyprowski #define DRM_EXYNOS_IPP_TASK_ASYNC	(1 << 1)
1029913f74fSMarek Szyprowski 
1039913f74fSMarek Szyprowski struct exynos_drm_ipp_formats {
1049913f74fSMarek Szyprowski 	uint32_t fourcc;
1059913f74fSMarek Szyprowski 	uint32_t type;
1069913f74fSMarek Szyprowski 	uint64_t modifier;
1079913f74fSMarek Szyprowski 	const struct drm_exynos_ipp_limit *limits;
1089913f74fSMarek Szyprowski 	unsigned int num_limits;
1099913f74fSMarek Szyprowski };
1109913f74fSMarek Szyprowski 
1119913f74fSMarek Szyprowski /* helper macros to set exynos_drm_ipp_formats structure and limits*/
1129913f74fSMarek Szyprowski #define IPP_SRCDST_MFORMAT(f, m, l) \
1139913f74fSMarek Szyprowski 	.fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
1149913f74fSMarek Szyprowski 	.num_limits = ARRAY_SIZE(l), \
1159913f74fSMarek Szyprowski 	.type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
1169913f74fSMarek Szyprowski 		 DRM_EXYNOS_IPP_FORMAT_DESTINATION)
1179913f74fSMarek Szyprowski 
1189913f74fSMarek Szyprowski #define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
1199913f74fSMarek Szyprowski 
1209913f74fSMarek Szyprowski #define IPP_SIZE_LIMIT(l, val...)	\
1219913f74fSMarek Szyprowski 	.type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
1229913f74fSMarek Szyprowski 		 DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
1239913f74fSMarek Szyprowski 
1249913f74fSMarek Szyprowski #define IPP_SCALE_LIMIT(val...)		\
1259913f74fSMarek Szyprowski 	.type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
1269913f74fSMarek Szyprowski 
1278b955034SInki Dae int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp,
1289913f74fSMarek Szyprowski 		const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
1299913f74fSMarek Szyprowski 		const struct exynos_drm_ipp_formats *formats,
1309913f74fSMarek Szyprowski 		unsigned int num_formats, const char *name);
1318b955034SInki Dae void exynos_drm_ipp_unregister(struct device *dev,
1329913f74fSMarek Szyprowski 			       struct exynos_drm_ipp *ipp);
1339913f74fSMarek Szyprowski 
1349913f74fSMarek Szyprowski void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
1359913f74fSMarek Szyprowski 
1369913f74fSMarek Szyprowski #ifdef CONFIG_DRM_EXYNOS_IPP
1379913f74fSMarek Szyprowski int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
1389913f74fSMarek Szyprowski 				 struct drm_file *file_priv);
1399913f74fSMarek Szyprowski int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
1409913f74fSMarek Szyprowski 				  struct drm_file *file_priv);
1419913f74fSMarek Szyprowski int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
1429913f74fSMarek Szyprowski 				    struct drm_file *file_priv);
1439913f74fSMarek Szyprowski int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
1449913f74fSMarek Szyprowski 				void *data, struct drm_file *file_priv);
1459913f74fSMarek Szyprowski #else
exynos_drm_ipp_get_res_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1469913f74fSMarek Szyprowski static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
1479913f74fSMarek Szyprowski 	 void *data, struct drm_file *file_priv)
1489913f74fSMarek Szyprowski {
1499913f74fSMarek Szyprowski 	struct drm_exynos_ioctl_ipp_get_res *resp = data;
1509913f74fSMarek Szyprowski 
1519913f74fSMarek Szyprowski 	resp->count_ipps = 0;
1529913f74fSMarek Szyprowski 	return 0;
1539913f74fSMarek Szyprowski }
exynos_drm_ipp_get_caps_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1549913f74fSMarek Szyprowski static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev,
1559913f74fSMarek Szyprowski 	 void *data, struct drm_file *file_priv)
1569913f74fSMarek Szyprowski {
1579913f74fSMarek Szyprowski 	return -ENODEV;
1589913f74fSMarek Szyprowski }
exynos_drm_ipp_get_limits_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1599913f74fSMarek Szyprowski static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev,
1609913f74fSMarek Szyprowski 	 void *data, struct drm_file *file_priv)
1619913f74fSMarek Szyprowski {
1629913f74fSMarek Szyprowski 	return -ENODEV;
1639913f74fSMarek Szyprowski }
exynos_drm_ipp_commit_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)1649913f74fSMarek Szyprowski static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
1659913f74fSMarek Szyprowski 	 void *data, struct drm_file *file_priv)
1669913f74fSMarek Szyprowski {
1679913f74fSMarek Szyprowski 	return -ENODEV;
1689913f74fSMarek Szyprowski }
1699913f74fSMarek Szyprowski #endif
1709913f74fSMarek Szyprowski #endif
171