xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/exynos/exynos_drm_ipp.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #ifndef _EXYNOS_DRM_IPP_H_
7*4882a593Smuzhiyun #define _EXYNOS_DRM_IPP_H_
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun struct exynos_drm_ipp;
10*4882a593Smuzhiyun struct exynos_drm_ipp_task;
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun /**
13*4882a593Smuzhiyun  * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun struct exynos_drm_ipp_funcs {
16*4882a593Smuzhiyun 	/**
17*4882a593Smuzhiyun 	 * @commit:
18*4882a593Smuzhiyun 	 *
19*4882a593Smuzhiyun 	 * This is the main entry point to start framebuffer processing
20*4882a593Smuzhiyun 	 * in the hardware. The exynos_drm_ipp_task has been already validated.
21*4882a593Smuzhiyun 	 * This function must not wait until the device finishes processing.
22*4882a593Smuzhiyun 	 * When the driver finishes processing, it has to call
23*4882a593Smuzhiyun 	 * exynos_exynos_drm_ipp_task_done() function.
24*4882a593Smuzhiyun 	 *
25*4882a593Smuzhiyun 	 * RETURNS:
26*4882a593Smuzhiyun 	 *
27*4882a593Smuzhiyun 	 * 0 on success or negative error codes in case of failure.
28*4882a593Smuzhiyun 	 */
29*4882a593Smuzhiyun 	int (*commit)(struct exynos_drm_ipp *ipp,
30*4882a593Smuzhiyun 		      struct exynos_drm_ipp_task *task);
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	/**
33*4882a593Smuzhiyun 	 * @abort:
34*4882a593Smuzhiyun 	 *
35*4882a593Smuzhiyun 	 * Informs the driver that it has to abort the currently running
36*4882a593Smuzhiyun 	 * task as soon as possible (i.e. as soon as it can stop the device
37*4882a593Smuzhiyun 	 * safely), even if the task would not have been finished by then.
38*4882a593Smuzhiyun 	 * After the driver performs the necessary steps, it has to call
39*4882a593Smuzhiyun 	 * exynos_drm_ipp_task_done() (as if the task ended normally).
40*4882a593Smuzhiyun 	 * This function does not have to (and will usually not) wait
41*4882a593Smuzhiyun 	 * until the device enters a state when it can be stopped.
42*4882a593Smuzhiyun 	 */
43*4882a593Smuzhiyun 	void (*abort)(struct exynos_drm_ipp *ipp,
44*4882a593Smuzhiyun 		      struct exynos_drm_ipp_task *task);
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /**
48*4882a593Smuzhiyun  * struct exynos_drm_ipp - central picture processor module structure
49*4882a593Smuzhiyun  */
50*4882a593Smuzhiyun struct exynos_drm_ipp {
51*4882a593Smuzhiyun 	struct drm_device *drm_dev;
52*4882a593Smuzhiyun 	struct device *dev;
53*4882a593Smuzhiyun 	struct list_head head;
54*4882a593Smuzhiyun 	unsigned int id;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	const char *name;
57*4882a593Smuzhiyun 	const struct exynos_drm_ipp_funcs *funcs;
58*4882a593Smuzhiyun 	unsigned int capabilities;
59*4882a593Smuzhiyun 	const struct exynos_drm_ipp_formats *formats;
60*4882a593Smuzhiyun 	unsigned int num_formats;
61*4882a593Smuzhiyun 	atomic_t sequence;
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun 	spinlock_t lock;
64*4882a593Smuzhiyun 	struct exynos_drm_ipp_task *task;
65*4882a593Smuzhiyun 	struct list_head todo_list;
66*4882a593Smuzhiyun 	wait_queue_head_t done_wq;
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun struct exynos_drm_ipp_buffer {
70*4882a593Smuzhiyun 	struct drm_exynos_ipp_task_buffer buf;
71*4882a593Smuzhiyun 	struct drm_exynos_ipp_task_rect rect;
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 	struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
74*4882a593Smuzhiyun 	const struct drm_format_info *format;
75*4882a593Smuzhiyun 	dma_addr_t dma_addr[MAX_FB_BUFFER];
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /**
79*4882a593Smuzhiyun  * struct exynos_drm_ipp_task - a structure describing transformation that
80*4882a593Smuzhiyun  * has to be performed by the picture processor hardware module
81*4882a593Smuzhiyun  */
82*4882a593Smuzhiyun struct exynos_drm_ipp_task {
83*4882a593Smuzhiyun 	struct device *dev;
84*4882a593Smuzhiyun 	struct exynos_drm_ipp *ipp;
85*4882a593Smuzhiyun 	struct list_head head;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	struct exynos_drm_ipp_buffer src;
88*4882a593Smuzhiyun 	struct exynos_drm_ipp_buffer dst;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	struct drm_exynos_ipp_task_transform transform;
91*4882a593Smuzhiyun 	struct drm_exynos_ipp_task_alpha alpha;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	struct work_struct cleanup_work;
94*4882a593Smuzhiyun 	unsigned int flags;
95*4882a593Smuzhiyun 	int ret;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	struct drm_pending_exynos_ipp_event *event;
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun #define DRM_EXYNOS_IPP_TASK_DONE	(1 << 0)
101*4882a593Smuzhiyun #define DRM_EXYNOS_IPP_TASK_ASYNC	(1 << 1)
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun struct exynos_drm_ipp_formats {
104*4882a593Smuzhiyun 	uint32_t fourcc;
105*4882a593Smuzhiyun 	uint32_t type;
106*4882a593Smuzhiyun 	uint64_t modifier;
107*4882a593Smuzhiyun 	const struct drm_exynos_ipp_limit *limits;
108*4882a593Smuzhiyun 	unsigned int num_limits;
109*4882a593Smuzhiyun };
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /* helper macros to set exynos_drm_ipp_formats structure and limits*/
112*4882a593Smuzhiyun #define IPP_SRCDST_MFORMAT(f, m, l) \
113*4882a593Smuzhiyun 	.fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
114*4882a593Smuzhiyun 	.num_limits = ARRAY_SIZE(l), \
115*4882a593Smuzhiyun 	.type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
116*4882a593Smuzhiyun 		 DRM_EXYNOS_IPP_FORMAT_DESTINATION)
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun #define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun #define IPP_SIZE_LIMIT(l, val...)	\
121*4882a593Smuzhiyun 	.type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
122*4882a593Smuzhiyun 		 DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun #define IPP_SCALE_LIMIT(val...)		\
125*4882a593Smuzhiyun 	.type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp,
128*4882a593Smuzhiyun 		const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
129*4882a593Smuzhiyun 		const struct exynos_drm_ipp_formats *formats,
130*4882a593Smuzhiyun 		unsigned int num_formats, const char *name);
131*4882a593Smuzhiyun void exynos_drm_ipp_unregister(struct device *dev,
132*4882a593Smuzhiyun 			       struct exynos_drm_ipp *ipp);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #ifdef CONFIG_DRM_EXYNOS_IPP
137*4882a593Smuzhiyun int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
138*4882a593Smuzhiyun 				 struct drm_file *file_priv);
139*4882a593Smuzhiyun int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
140*4882a593Smuzhiyun 				  struct drm_file *file_priv);
141*4882a593Smuzhiyun int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
142*4882a593Smuzhiyun 				    struct drm_file *file_priv);
143*4882a593Smuzhiyun int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
144*4882a593Smuzhiyun 				void *data, struct drm_file *file_priv);
145*4882a593Smuzhiyun #else
exynos_drm_ipp_get_res_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)146*4882a593Smuzhiyun static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
147*4882a593Smuzhiyun 	 void *data, struct drm_file *file_priv)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	struct drm_exynos_ioctl_ipp_get_res *resp = data;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	resp->count_ipps = 0;
152*4882a593Smuzhiyun 	return 0;
153*4882a593Smuzhiyun }
exynos_drm_ipp_get_caps_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)154*4882a593Smuzhiyun static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev,
155*4882a593Smuzhiyun 	 void *data, struct drm_file *file_priv)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun 	return -ENODEV;
158*4882a593Smuzhiyun }
exynos_drm_ipp_get_limits_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)159*4882a593Smuzhiyun static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev,
160*4882a593Smuzhiyun 	 void *data, struct drm_file *file_priv)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	return -ENODEV;
163*4882a593Smuzhiyun }
exynos_drm_ipp_commit_ioctl(struct drm_device * dev,void * data,struct drm_file * file_priv)164*4882a593Smuzhiyun static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
165*4882a593Smuzhiyun 	 void *data, struct drm_file *file_priv)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun 	return -ENODEV;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun #endif
170*4882a593Smuzhiyun #endif
171