@@ -129,12 +129,17 @@ static void apple_plane_atomic_update(struct drm_plane *plane,
129129 /* Handled in atomic_flush */
130130}
131131
132- static const struct drm_plane_helper_funcs apple_plane_helper_funcs = {
132+ static const struct drm_plane_helper_funcs apple_primary_plane_helper_funcs = {
133133 .atomic_check = apple_plane_atomic_check ,
134134 .atomic_update = apple_plane_atomic_update ,
135135 .get_scanout_buffer = drm_fb_dma_get_scanout_buffer ,
136136};
137137
138+ static const struct drm_plane_helper_funcs apple_plane_helper_funcs = {
139+ .atomic_check = apple_plane_atomic_check ,
140+ .atomic_update = apple_plane_atomic_update ,
141+ };
142+
138143static void apple_plane_cleanup (struct drm_plane * plane )
139144{
140145 drm_plane_cleanup (plane );
@@ -161,14 +166,19 @@ static const struct drm_plane_funcs apple_plane_funcs = {
161166 * doesn't matter for the primary plane, but cursors/overlays must not
162167 * advertise formats without alpha.
163168 */
164- static const u32 dcp_formats [] = {
169+ static const u32 dcp_primary_formats [] = {
165170 DRM_FORMAT_XRGB2101010 ,
166171 DRM_FORMAT_XRGB8888 ,
167172 DRM_FORMAT_ARGB8888 ,
168173 DRM_FORMAT_XBGR8888 ,
169174 DRM_FORMAT_ABGR8888 ,
170175};
171176
177+ static const u32 dcp_overlay_formats [] = {
178+ DRM_FORMAT_ARGB8888 ,
179+ DRM_FORMAT_ABGR8888 ,
180+ };
181+
172182u64 apple_format_modifiers [] = {
173183 DRM_FORMAT_MOD_LINEAR ,
174184 DRM_FORMAT_MOD_INVALID
@@ -183,14 +193,31 @@ static struct drm_plane *apple_plane_init(struct drm_device *dev,
183193
184194 plane = kzalloc (sizeof (* plane ), GFP_KERNEL );
185195
186- ret = drm_universal_plane_init (dev , plane , possible_crtcs ,
196+ switch (type ) {
197+ case DRM_PLANE_TYPE_PRIMARY :
198+ ret = drm_universal_plane_init (dev , plane , possible_crtcs ,
187199 & apple_plane_funcs ,
188- dcp_formats , ARRAY_SIZE (dcp_formats ),
200+ dcp_primary_formats , ARRAY_SIZE (dcp_primary_formats ),
189201 apple_format_modifiers , type , NULL );
202+ break ;
203+ case DRM_PLANE_TYPE_OVERLAY :
204+ case DRM_PLANE_TYPE_CURSOR :
205+ ret = drm_universal_plane_init (dev , plane , possible_crtcs ,
206+ & apple_plane_funcs ,
207+ dcp_overlay_formats , ARRAY_SIZE (dcp_overlay_formats ),
208+ apple_format_modifiers , type , NULL );
209+ break ;
210+ default :
211+ return NULL ;
212+ }
213+
190214 if (ret )
191215 return ERR_PTR (ret );
192216
193- drm_plane_helper_add (plane , & apple_plane_helper_funcs );
217+ if (type == DRM_PLANE_TYPE_PRIMARY )
218+ drm_plane_helper_add (plane , & apple_primary_plane_helper_funcs );
219+ else
220+ drm_plane_helper_add (plane , & apple_plane_helper_funcs );
194221
195222 return plane ;
196223}
@@ -390,16 +417,29 @@ static int apple_probe_per_dcp(struct device *dev,
390417 struct apple_crtc * crtc ;
391418 struct apple_connector * connector ;
392419 struct apple_encoder * enc ;
393- struct drm_plane * primary ;
394- int ret ;
420+ struct drm_plane * planes [DCP_MAX_PLANES ];
421+ int ret , i ;
422+
423+ planes [0 ] = apple_plane_init (drm , 1U << num , DRM_PLANE_TYPE_PRIMARY );
424+ if (IS_ERR (planes [0 ]))
425+ return PTR_ERR (planes [0 ]);
395426
396- primary = apple_plane_init (drm , 1U << num , DRM_PLANE_TYPE_PRIMARY );
397427
398- if (IS_ERR (primary ))
399- return PTR_ERR (primary );
428+ /* Set up our other planes */
429+ for (i = 1 ; i < DCP_MAX_PLANES ; i ++ ) {
430+ planes [i ] = apple_plane_init (drm , 1U << num , DRM_PLANE_TYPE_OVERLAY );
431+ if (IS_ERR (planes [i ]))
432+ return PTR_ERR (planes [i ]);
433+ }
400434
435+ /*
436+ * Even though we have an overlay plane, we cannot expose it to legacy
437+ * userspace for cursors as we cannot make the same guarantees as ye olde
438+ * hardware cursor planes such userspace would expect us to. Modern userspace
439+ * knows what to do with overlays.
440+ */
401441 crtc = kzalloc (sizeof (* crtc ), GFP_KERNEL );
402- ret = drm_crtc_init_with_planes (drm , & crtc -> base , primary , NULL ,
442+ ret = drm_crtc_init_with_planes (drm , & crtc -> base , planes [ 0 ] , NULL ,
403443 & apple_crtc_funcs , NULL );
404444 if (ret )
405445 return ret ;
0 commit comments