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