xref: /openbsd-src/sys/dev/pci/drm/apple/iomfb_internal.h (revision 5dd0baa8251145fcf503b060e3a9291086883454)
1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /* Copyright The Asahi Linux Contributors */
3 
4 #include <drm/drm_modes.h>
5 #include <drm/drm_rect.h>
6 
7 #include "dcp-internal.h"
8 
9 struct apple_dcp;
10 
11 typedef void (*dcp_callback_t)(struct apple_dcp *, void *, void *);
12 
13 
14 #define DCP_THUNK_VOID(func, handle)                                         \
15 	static void func(struct apple_dcp *dcp, bool oob, dcp_callback_t cb, \
16 			 void *cookie)                                       \
17 	{                                                                    \
18 		dcp_push(dcp, oob, &dcp_methods[handle], 0, 0, NULL, cb, cookie);          \
19 	}
20 
21 #define DCP_THUNK_OUT(func, handle, T)                                       \
22 	static void func(struct apple_dcp *dcp, bool oob, dcp_callback_t cb, \
23 			 void *cookie)                                       \
24 	{                                                                    \
25 		dcp_push(dcp, oob, &dcp_methods[handle], 0, sizeof(T), NULL, cb, cookie);  \
26 	}
27 
28 #define DCP_THUNK_IN(func, handle, T)                                       \
29 	static void func(struct apple_dcp *dcp, bool oob, T *data,          \
30 			 dcp_callback_t cb, void *cookie)                   \
31 	{                                                                   \
32 		dcp_push(dcp, oob, &dcp_methods[handle], sizeof(T), 0, data, cb, cookie); \
33 	}
34 
35 #define DCP_THUNK_INOUT(func, handle, T_in, T_out)                            \
36 	static void func(struct apple_dcp *dcp, bool oob, T_in *data,         \
37 			 dcp_callback_t cb, void *cookie)                     \
38 	{                                                                     \
39 		dcp_push(dcp, oob, &dcp_methods[handle], sizeof(T_in), sizeof(T_out), data, \
40 			 cb, cookie);                                         \
41 	}
42 
43 #define IOMFB_THUNK_INOUT(name)                                     \
44 	static void iomfb_ ## name(struct apple_dcp *dcp, bool oob, \
45 			struct iomfb_ ## name ## _req *data,        \
46 			dcp_callback_t cb, void *cookie)            \
47 	{                                                           \
48 		dcp_push(dcp, oob, &dcp_methods[iomfbep_ ## name],                \
49 			 sizeof(struct iomfb_ ## name ## _req),     \
50 			 sizeof(struct iomfb_ ## name ## _resp),    \
51 			 data,  cb, cookie);                        \
52 	}
53 
54 /*
55  * Define type-safe trampolines. Define typedefs to enforce type-safety on the
56  * input data (so if the types don't match, gcc errors out).
57  */
58 
59 #define TRAMPOLINE_VOID(func, handler)                                        \
60 	static bool __maybe_unused func(struct apple_dcp *dcp, int tag, void *out, void *in) \
61 	{                                                                     \
62 		trace_iomfb_callback(dcp, tag, #handler);                     \
63 		handler(dcp);                                                 \
64 		return true;                                                  \
65 	}
66 
67 #define TRAMPOLINE_IN(func, handler, T_in)                                    \
68 	typedef void (*callback_##handler)(struct apple_dcp *, T_in *);       \
69                                                                               \
70 	static bool __maybe_unused func(struct apple_dcp *dcp, int tag, void *out, void *in) \
71 	{                                                                     \
72 		callback_##handler cb = handler;                              \
73                                                                               \
74 		trace_iomfb_callback(dcp, tag, #handler);                     \
75 		cb(dcp, in);                                                  \
76 		return true;                                                  \
77 	}
78 
79 #define TRAMPOLINE_INOUT(func, handler, T_in, T_out)                          \
80 	typedef T_out (*callback_##handler)(struct apple_dcp *, T_in *);      \
81                                                                               \
82 	static bool __maybe_unused func(struct apple_dcp *dcp, int tag, void *out, void *in) \
83 	{                                                                     \
84 		T_out *typed_out = out;                                       \
85 		callback_##handler cb = handler;                              \
86                                                                               \
87 		trace_iomfb_callback(dcp, tag, #handler);                     \
88 		*typed_out = cb(dcp, in);                                     \
89 		return true;                                                  \
90 	}
91 
92 #define TRAMPOLINE_OUT(func, handler, T_out)                                  \
93 	static bool __maybe_unused func(struct apple_dcp *dcp, int tag, void *out, void *in) \
94 	{                                                                     \
95 		T_out *typed_out = out;                                       \
96                                                                               \
97 		trace_iomfb_callback(dcp, tag, #handler);                     \
98 		*typed_out = handler(dcp);                                    \
99 		return true;                                                  \
100 	}
101 
102 /* Call a DCP function given by a tag */
103 void dcp_push(struct apple_dcp *dcp, bool oob, const struct dcp_method_entry *call,
104 		     u32 in_len, u32 out_len, void *data, dcp_callback_t cb,
105 		     void *cookie);
106 
107 /* Parse a callback tag "D123" into the ID 123. Returns -EINVAL on failure. */
108 int dcp_parse_tag(char tag[4]);
109 
110 void dcp_ack(struct apple_dcp *dcp, enum dcp_context_id context);
111 
112 /*
113  * DRM specifies rectangles as start and end coordinates.  DCP specifies
114  * rectangles as a start coordinate and a width/height. Convert a DRM rectangle
115  * to a DCP rectangle.
116  */
117 struct dcp_rect drm_to_dcp_rect(struct drm_rect *rect);
118 
119 u32 drm_format_to_dcp(u32 drm);
120 
121 /* The user may own drm_display_mode, so we need to search for our copy */
122 struct dcp_display_mode *lookup_mode(struct apple_dcp *dcp,
123 					    const struct drm_display_mode *mode);
124