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