|
26 | 26 | #include <drm/drm_drv.h> |
27 | 27 | #include <drm/drm_fb_helper.h> |
28 | 28 | #include <drm/drm_fbdev_dma.h> |
29 | | -#include <drm/drm_fourcc.h> |
30 | 29 | #include <drm/drm_fb_dma_helper.h> |
31 | 30 | #include <drm/drm_gem_dma_helper.h> |
32 | 31 | #include <drm/drm_gem_framebuffer_helper.h> |
|
40 | 39 | #include <drm/drm_fixed.h> |
41 | 40 |
|
42 | 41 | #include "dcp.h" |
| 42 | +#include "plane.h" |
43 | 43 |
|
44 | 44 | #define DRIVER_NAME "apple" |
45 | 45 | #define DRIVER_DESC "Apple display controller DRM driver" |
46 | 46 |
|
47 | | -#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) |
48 | | - |
49 | 47 | #define MAX_COPROCESSORS 3 |
50 | 48 |
|
51 | 49 | struct apple_drm_private { |
@@ -77,172 +75,6 @@ static const struct drm_driver apple_drm_driver = { |
77 | 75 | .fops = &apple_fops, |
78 | 76 | }; |
79 | 77 |
|
80 | | -static int apple_plane_atomic_check(struct drm_plane *plane, |
81 | | - struct drm_atomic_state *state) |
82 | | -{ |
83 | | - struct drm_plane_state *new_plane_state; |
84 | | - struct drm_crtc_state *crtc_state; |
85 | | - struct drm_rect *dst; |
86 | | - int ret; |
87 | | - |
88 | | - new_plane_state = drm_atomic_get_new_plane_state(state, plane); |
89 | | - |
90 | | - if (!new_plane_state->crtc) |
91 | | - return 0; |
92 | | - |
93 | | - crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc); |
94 | | - if (IS_ERR(crtc_state)) |
95 | | - return PTR_ERR(crtc_state); |
96 | | - |
97 | | - /* |
98 | | - * DCP limits downscaling to 2x and upscaling to 4x. Attempting to |
99 | | - * scale outside these bounds errors out when swapping. |
100 | | - * |
101 | | - * This function also takes care of clipping the src/dest rectangles, |
102 | | - * which is required for correct operation. Partially off-screen |
103 | | - * surfaces may appear corrupted. |
104 | | - * |
105 | | - * DCP does not distinguish plane types in the hardware, so we set |
106 | | - * can_position. If the primary plane does not fill the screen, the |
107 | | - * hardware will fill in zeroes (black). |
108 | | - */ |
109 | | - ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state, |
110 | | - FRAC_16_16(1, 2), |
111 | | - FRAC_16_16(4, 1), |
112 | | - true, true); |
113 | | - if (ret < 0) |
114 | | - return ret; |
115 | | - |
116 | | - if (!new_plane_state->visible) |
117 | | - return 0; |
118 | | - |
119 | | - /* |
120 | | - * DCP does not allow a surface to clip off the screen, and will crash |
121 | | - * if any blended surface is smaller than 32x32. Reject the atomic op |
122 | | - * if the plane will crash DCP. |
123 | | - * |
124 | | - * This is most pertinent to cursors. Userspace should fall back to |
125 | | - * software cursors if the plane check is rejected. |
126 | | - */ |
127 | | - dst = &new_plane_state->dst; |
128 | | - if (drm_rect_width(dst) < 32 || drm_rect_height(dst) < 32) { |
129 | | - dev_err_once(state->dev->dev, |
130 | | - "Plane operation would have crashed DCP! Rejected!\n\ |
131 | | - DCP requires 32x32 of every plane to be within screen space.\n\ |
132 | | - Your compositor asked to overlay [%dx%d, %dx%d] on %dx%d.\n\ |
133 | | - This is not supported, and your compositor should have\n\ |
134 | | - switched to software compositing when this operation failed.\n\ |
135 | | - You should not have noticed this at all. If your screen\n\ |
136 | | - froze/hitched, or your compositor crashed, please report\n\ |
137 | | - this to the your compositor's developers. We will not\n\ |
138 | | - throw this error again until you next reboot.\n", |
139 | | - dst->x1, dst->y1, dst->x2, dst->y2, |
140 | | - crtc_state->mode.hdisplay, crtc_state->mode.vdisplay); |
141 | | - return -EINVAL; |
142 | | - } |
143 | | - |
144 | | - return 0; |
145 | | -} |
146 | | - |
147 | | -static void apple_plane_atomic_update(struct drm_plane *plane, |
148 | | - struct drm_atomic_state *state) |
149 | | -{ |
150 | | - /* Handled in atomic_flush */ |
151 | | -} |
152 | | - |
153 | | -static const struct drm_plane_helper_funcs apple_primary_plane_helper_funcs = { |
154 | | - .atomic_check = apple_plane_atomic_check, |
155 | | - .atomic_update = apple_plane_atomic_update, |
156 | | - .get_scanout_buffer = drm_fb_dma_get_scanout_buffer, |
157 | | -}; |
158 | | - |
159 | | -static const struct drm_plane_helper_funcs apple_plane_helper_funcs = { |
160 | | - .atomic_check = apple_plane_atomic_check, |
161 | | - .atomic_update = apple_plane_atomic_update, |
162 | | -}; |
163 | | - |
164 | | -static void apple_plane_cleanup(struct drm_plane *plane) |
165 | | -{ |
166 | | - drm_plane_cleanup(plane); |
167 | | - kfree(plane); |
168 | | -} |
169 | | - |
170 | | -static const struct drm_plane_funcs apple_plane_funcs = { |
171 | | - .update_plane = drm_atomic_helper_update_plane, |
172 | | - .disable_plane = drm_atomic_helper_disable_plane, |
173 | | - .destroy = apple_plane_cleanup, |
174 | | - .reset = drm_atomic_helper_plane_reset, |
175 | | - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, |
176 | | - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, |
177 | | -}; |
178 | | - |
179 | | -/* |
180 | | - * Table of supported formats, mapping from DRM fourccs to DCP fourccs. |
181 | | - * |
182 | | - * For future work, DCP supports more formats not listed, including YUV |
183 | | - * formats, an extra RGBA format, and a biplanar RGB10_A8 format (fourcc b3a8) |
184 | | - * used for HDR. |
185 | | - * |
186 | | - * Note: we don't have non-alpha formats but userspace breaks without XRGB. It |
187 | | - * doesn't matter for the primary plane, but cursors/overlays must not |
188 | | - * advertise formats without alpha. |
189 | | - */ |
190 | | -static const u32 dcp_primary_formats[] = { |
191 | | - DRM_FORMAT_XRGB2101010, |
192 | | - DRM_FORMAT_XRGB8888, |
193 | | - DRM_FORMAT_ARGB8888, |
194 | | - DRM_FORMAT_XBGR8888, |
195 | | - DRM_FORMAT_ABGR8888, |
196 | | -}; |
197 | | - |
198 | | -static const u32 dcp_overlay_formats[] = { |
199 | | - DRM_FORMAT_ARGB8888, |
200 | | - DRM_FORMAT_ABGR8888, |
201 | | -}; |
202 | | - |
203 | | -u64 apple_format_modifiers[] = { |
204 | | - DRM_FORMAT_MOD_LINEAR, |
205 | | - DRM_FORMAT_MOD_INVALID |
206 | | -}; |
207 | | - |
208 | | -static struct drm_plane *apple_plane_init(struct drm_device *dev, |
209 | | - unsigned long possible_crtcs, |
210 | | - enum drm_plane_type type) |
211 | | -{ |
212 | | - int ret; |
213 | | - struct drm_plane *plane; |
214 | | - |
215 | | - plane = kzalloc(sizeof(*plane), GFP_KERNEL); |
216 | | - |
217 | | - switch (type) { |
218 | | - case DRM_PLANE_TYPE_PRIMARY: |
219 | | - ret = drm_universal_plane_init(dev, plane, possible_crtcs, |
220 | | - &apple_plane_funcs, |
221 | | - dcp_primary_formats, ARRAY_SIZE(dcp_primary_formats), |
222 | | - apple_format_modifiers, type, NULL); |
223 | | - break; |
224 | | - case DRM_PLANE_TYPE_OVERLAY: |
225 | | - case DRM_PLANE_TYPE_CURSOR: |
226 | | - ret = drm_universal_plane_init(dev, plane, possible_crtcs, |
227 | | - &apple_plane_funcs, |
228 | | - dcp_overlay_formats, ARRAY_SIZE(dcp_overlay_formats), |
229 | | - apple_format_modifiers, type, NULL); |
230 | | - break; |
231 | | - default: |
232 | | - return NULL; |
233 | | - } |
234 | | - |
235 | | - if (ret) |
236 | | - return ERR_PTR(ret); |
237 | | - |
238 | | - if (type == DRM_PLANE_TYPE_PRIMARY) |
239 | | - drm_plane_helper_add(plane, &apple_primary_plane_helper_funcs); |
240 | | - else |
241 | | - drm_plane_helper_add(plane, &apple_plane_helper_funcs); |
242 | | - |
243 | | - return plane; |
244 | | -} |
245 | | - |
246 | 78 | static enum drm_connector_status |
247 | 79 | apple_connector_detect(struct drm_connector *connector, bool force) |
248 | 80 | { |
|
0 commit comments