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